Feature: Label components (without fields)

Components without any fields currently crash the ECS. See below for reproducing code and the resulting error.
Such components, however, can be very useful as labels. Not each components needs data, sometimes it is enough for it to just be there.
Some ECS implement labels as a shared/singleton object to avoid the need for multiple instances. Not sure if this would be possible here. Basically, just have a bitmask for it, but no component storage (or rather, a single object).
package main

import ecs "github.com/marioolofo/go-gameengine-ecs"

const LabelCompID ecs.ID = 0

type LabelComp struct{}

func main() {
	world := ecs.NewWorld()
	config := []ecs.ComponentConfig{
		{ID: LabelCompID, Component: LabelComp{}},
	}
	world.RegisterComponents(config...)

	entity := world.NewEntity()
	world.Assign(entity, LabelCompID)
}

panic: runtime error: index out of range [0] with length 0

goroutine 1 [running]:
github.com/marioolofo/go-gameengine-ecs.(*memPool).Get(...)
        C:/Users/mlange/go/pkg/mod/github.com/marioolofo/go-gameengine-ecs@v0.0.0-20220425170333-4085b0fb7de4/mempool.go:125
github.com/marioolofo/go-gameengine-ecs.(*memPool).Alloc(0xc0000640a0)
        C:/Users/mlange/go/pkg/mod/github.com/marioolofo/go-gameengine-ecs@v0.0.0-20220425170333-4085b0fb7de4/mempool.go:113
+0x265
github.com/marioolofo/go-gameengine-ecs.(*system).New(0xc0000583e0, 0x0?)
        C:/Users/mlange/go/pkg/mod/github.com/marioolofo/go-gameengine-ecs@v0.0.0-20220425170333-4085b0fb7de4/system.go:59 +0x6b
github.com/marioolofo/go-gameengine-ecs.(*world).assign(0xc000132000, 0x1, {0xc000018088, 0x1, 0x77dbcb?})
        C:/Users/mlange/go/pkg/mod/github.com/marioolofo/go-gameengine-ecs@v0.0.0-20220425170333-4085b0fb7de4/world.go:324 +0x78
github.com/marioolofo/go-gameengine-ecs.(*world).Assign(0xc000132000, 0x1, {0xc000018088, 0x1, 0x1})
        C:/Users/mlange/go/pkg/mod/github.com/marioolofo/go-gameengine-ecs@v0.0.0-20220425170333-4085b0fb7de4/world.go:205 +0xe7
main.main()
        C:/Data/Hack/Go/go-ecs-test/cmd/labels/main.go:13 +0xab
exit status 2

I imagine that's a easy way to solve this, just adding a parameter IsStatic bool to the ComponentConfig struct, and then using the template value as reference to return in every get for this component. Do you have any other idea?

Sounds like a good solution and would also allow for common global attibutes of certain agents. This would probably make a few situations easier where one would otherwide need to use a "resource".
Probably types withourt fields should also be "static" (actually, if "it" can have mutale fields, it is not static), as different instances can't be distinguished and make no sense. I think it crashed in this case?

Do you have any other idea?

Regarding label components, or in general?
Due to the lack of mature ECS's in Go (your one probably among the best), I felt inclined to start another one: https://github.com/mlange-42/arche. Got it quite far in 3 days. In a most simple example, it beats your iteration speed by factor 3. Sorry... 😉
Did you do in-depth profiling to find potential bottlenecks? E.g. I found (only 2 months of Go experience...), that using constructors that return pointers for things like mempool degrade memory access performance quite a bit. Sure, heap allocation...
You may want to take a look at entity_pool.go for entity recycling and generations stuff. Really cool algorithm, see the link in there.
Implemented a non-pages version of your mempool. When attempting to transit to a paged version to avoid re-allocations, iteration performance degraded by around 50%. Too bad!

Probably types withourt fields should also be "static" (actually, if "it" can have mutale fields, it is not static), as different instances can't be distinguished and make no sense. I think it crashed in this case?

Exactly, so static it is.
I can see a use for this, as I had to do something similar long time ago in Unity to manage the game's sound/music.
I think that it crashed because of the reflection trying to allocate an array with zero size structs.

Regarding label components, or in general?

About the labels. I'll implement that way and see how it goes.

Did you do in-depth profiling to find potential bottlenecks? E.g. I found (only 2 months of Go experience...), that using constructors that return pointers for things like mempool degrade memory access performance quite a bit. Sure, heap allocation...

Didn't profile this yet, but I think that it's more correct to return the pointer, as if you copy the struct around, the internal state may be changed in one copy but not replicated in the other.

You may want to take a look at entity_pool.go for entity recycling and generations stuff. Really cool algorithm, see the link in there.

Thank you, I will definetively look at it.

Implemented a non-pages version of your mempool. When attempting to transit to a paged version to avoid re-allocations, iteration performance degraded by around 50%. Too bad!

That's interesting, I'll implement a non paged version to compare. The only benefit of pages is that the components always have the same address for all it's lifetime, so you can cache it. When you resize the memory pool, you have to ensure that you're not inside an update loop or something like that, so the complexity grows (or you have to leave the responsability of correct usage to the user)
I'll add your package to my benchmark tests if you don't mind =D

Didn't profile this yet, but I think that it's more correct to return the pointer, as if you copy the struct around, the internal state may be changed in one copy but not replicated in the other.

I mean just at construction and in the "parent" container. Like this:
type World struct {
    Archetypes []Archetype
}

instead of
type World struct {
    Archetypes []*Archetype
}

When passing things around then, pointers are fine. It's about where the memory is allocated in the first place I think.
(but keep in mind: don't iterate this with a for range loop, use index and pointer instead).

Thank you, I will definetively look at it.

It's really simple and a very cool algorithm IMO!

The benefit of pages is that the components always have the same address for all it's lifetime, so you can cache it.

Wanted it primarily to avoid the copying when extending a buffer that is on it's capacity, and to avoid having the GC need to collect the old buffer.
Component caching isn't a good thing I think, at least over update step boundaries. I would always use the entity for this, as you can then check if it is still there at all, and if it still has the component (the component could be orphaned otherwise, or the memory location could be re-used by a fresh instance).
However, persistent memory locations for components are not possible with archetypes. Entites and their components are moved between archetypes when the composition changes. And archetypes stay completely packed (using swap-remove). Which is the original purpose of the approach: linear access to contigious, packed memory.
I went for a "hard" lock approach for now. So a Query locks the world when created, and unlocks (it's lock bit) when iteration is done. No buffering of operation on the world side as you do, but I may add this in the future. The user has to do this in the moment. Currently, it just panics 😉

I'll add your package to my benchmark tests if you don't mind =D

Sure, that's just fair! Feel free put it under stress, keen to see the results.

Yeah I think that you're correct in this regard, the array of archetype may be faster without pointer, but I dunno how much.

It's really simple and a very cool algorithm IMO!

I have a background in embedded systems, and I had something similar to this algorithm, but I exploited the fact
that the min allocation block size is equal a word for the processor, so I just stored the address to the next free block inside the index. This way, you just need a uintptr to point to the first free block address, and there you'll automatically have a linked list of free blocks.
The first implementation that I tried before upload to github was with archetypes, but it was very slow, so I just migrate to this separate component lists. Don't know if it's easy to do some grouped components interleaved for the archetype without slowing down the entire ECS.
If you think about it, interleaved components equal the basic archetype pattern will have some hot access structures with some not so much accessed, increasing the cache misses, but it need to be checked.

Component caching isn't a good thing I think, at least over update step boundaries. I would always use the entity for this, as you can then check if it is still there at all, and if it still has the component (the component could be orphaned otherwise, or the memory location could be re-used by a fresh instance).

Yes, when I created the package it was a great idea, but I don't know if it's really necessary at all. If it's slow, I'll probably refactor this and include parameters in the component config to indicates how much it must grow instead to fine tune project by project.
I'll benchmark your package too, I don't understand exactly why you're having so better performance in your tests, as the best performance we can have is acessing just indices in the array for components without reflection and casting, as LecsGO does...

Don't know if it's easy to do some grouped components interleaved for the archetype without slowing down the entire ECS.

What do you mean by "interleaved for the archetype" here?
Did you take a look at my implementation? Maybe I misunderstand, but maybe this helps:

Each archetype is a separate data structure
Each archetype has a "column" (storage/mempool) for entities
Each archetype has a "column" for each component is contains
"Columns" are kept in sync, appending or swap-removing entire "rows" when an entity enters or exits
For lookup by entity (i.e. not in iterations), the world has a entity-indexed slice to look up where to find it's components (which archetype, which index).

So in essence, components are not interleaved(?) by archetype, but rather stored by archetype.
(Which means things get copied around when entity composition changes)
So basically, in my implementation iterating a query is always non-interleaved. I think with sparse sets, stuff is interleaved/you jump around memory when accessing components. (Except if you somehow have sorted entities in your filters, not sure. But you would still have gaps/jumps).

I'll benchmark your package too, I don't understand exactly why you're having so better performance in your tests, as the best performance we can have is acessing just indices in the array for components without reflection and casting, as LecsGO does...

I think we are both on the good side here. Using only integers everywhere... Otherwise, we would talk about orders of magnitude in performance difference.
Putting the potential jumps/gaps on memory traversal aside, although it might have an impact...
What I observe when tweaking is that memory access seems already near optimal, and small changes like an if more or less, or another array lookup, can make tens of percent of a difference.
Further, just to check, you could test getting rid of your "pointer constructors" (and thus unfortunately also interfaces). It really made a difference for me. And copying is only involved during initialization. (not sure if returning a struct [immediately] makes a copy).
Too bad that this point conflics with interfaces (or I just missed something although Go is such a small language).

What do you mean by "interleaved for the archetype" here?

When I read about archetypes, what I understood is that the components are allocated for that archetype in a unique array, for example:
Entity have components A, B, the memory pool for this archetype would be [A,B,A,B,A,B...] and the size of the archetype is the sum of all its components. This is what I called interleaved arrays (don't know if it's the correct description of this type of array, is just the name that was given to a type of vertex arrays in graphics).

Putting the potential jumps/gaps on memory traversal aside, although it might have an impact...
What I observe when tweaking is that memory access seems already near optimal, and small changes like an if more or less, or another array lookup, can make tens of percent of a difference.

Yes, one of the "problems" I have now is the sparse array indirection. In some tests that I did yesterday, Go checks every array access for out of bounds. So there's a lot of branching paths in the way. When I removed the sparse array in favor to directly access the memory pool, I got an increase of 30% in performance.
Did some tests with pagination vs single array for memory pools, got the same results, not a single bit of performance increase. Created an memory pool with generics to remove the reflect from the code, but got the same results in performance!

Did you take a look at my implementation? Maybe I misunderstand, but maybe this helps:

Yes, basically you're following the EnTT design right? When I created this package, I just found more references of flecs implementations, so I borrowed the sparse array idea from it.

For generics, I don't see how to use them here given how they work in Go. Would require (a flexible number of) generics for the world too, and even for archetypes in my case.

I was able to keep the code pratically equal, changing only the implementation, for example:
type MemoryPool interface {
  Alloc, Get, Set, ...
}

type memPool[T any] struct {
  data []T
}

// implementation of memPool[T]
...
//

func NewMemoryPool[T any](cap int) {
  return memPool[T] {
     make([]T, 0, cap)
  }
}

here, you I had to change the NewSystem to be generic as well.
Now, in my case, I register the components in NewWorld or AddComponents. I had to change this and register them like this:
func (w *World) AddSystem(id ID, System) {
  ....
}

w := NewWorld()
w.AddSystem(PhysicsComponentID, NewSystem[Physics2D]( InitialComponentCapacity ))

as I understand, every call to NewSystem with a concrete type will compile a complete variation of System for that type, but as it is behind the System interface, there's no need to change anything else.

In my implementation, archetypes look like this (one "array" per column, first column is the entity):
|e|A|B|
|e|A|B|
|e|A|B|
Regarding paging, I tried the left approach, which caused a slowdown. Will probably also try the right approach:
|e|A|B|   |e|A|B|
|e|A|B|   |e|A|B|
|e|A|B|   |e|A|B|
|-|-|-|   -------
|e|A|B|   |e|A|B|
|e|A|B|   |e|A|B|

Thanks for the idea and clarification. For this setup the use of pages will indeed add complexity where it should be none
I'll see if I can test some more ideas and update the package this weekend

as I understand, every call to NewSystem with a concrete type will compile a complete variation of System for that type, but as it is behind the System interface, there's no need to change anything else.

Ah, ok, the user registers the systems (and essentially also mempools) manually... How do you store them in the world then? As wildcard generics are not possible in Go...
Also preparing a bit of documentation on the Arche design right now. So here the current text and illustration FYI...

Arche architecture
Arche uses an archetype-based architecture.
The ASCII graph below illustrates the architecture. Components for entities are stored in so-called archetypes, which represent unique combinations of components. In the illustration, the first archetype holds all components for all entities with (only/exactly) the components A, B and C.
 Entities   Archetypes   Bitmasks   Queries

   E         E Comps
  |0|       |2|A|B|C|    111...<-.<--------.
  |1|---.   |8|A|B|C|            |         |
  |2|   '-->|1|A|B|C|            |         |
  |3|       |3|A|B|C|            |--(A, C) |
  |4|                            |  101... |
  |6|   .-->|7|A|C|      101...<-'         |--(B)
  |7|---'   |6|A|C|                        |  010...
  |8|       |4|A|C|                        |
  |9|---.                                  |
  |.|   |   |5|B|C|      010...   <--------'
  |.|   '-->|9|B|C|
  |.|
  |.| <===> [Entity pool]

The exact composition of each archetype is encoded in a bitmask for fast comparison. Thus, queries can easily identify their relevant archetypes (i.e. query bitmask contained in archetype bitmask), and then iterate entities linearly, and very fast. Components can be accessed through the query in a very efficient way.
For getting components by entity ID, e.g. for hierarchies, the world contains a list that is indexed by the entity ID, and references the entity's archetype and index in the archetype. This way, getting components for entity IDs (i.e. random access) is fast, although not as fast as in queries.
Obviously, archetypes are an optimization for iteration speed. But they also come with a downside. Adding or removing components to/from an entity requires moving all the components of the entity to another archetype. It is therefore recommended to add/remove/exchange multiple components at the same time rather than one after the other.

Ah, ok, the user registers the systems (and essentially also mempools) manually... How do you store them in the world then? As wildcard generics are not possible in Go...

The rest of the code is not changed, as the System interface already encapsulates the correct instance. Think of it as if you did something like this in C++
class IStorage {
   virtual void* Alloc() = 0;
    ...
}

template <typename T>
class Storage : public IStorage {
public:
   void* Alloc();

 private:
    std::vector<T> data;
};

new Storage<Physics2D>();
new Storage<Transform2D>();
new Storage<TurretTracking>();

when you declare a concrete Storage type, the compiler will implement the concrete class and, on instantiation, populate the correct function map for the given type to fulfill the IStorage interface.

Also preparing a bit of documentation on the Arche design right now. So here the current text and illustration FYI...

Thanks, I'll try something like this for the next iteration of this package. I can see that the access to components is faster and can be more efficient than the sparse array.

Ah, ok, you hold the interface...
Would not work with archetypes I think, as they and their (potentially generic) columns can't be created by the user.

Ah, a small addition: Query is a one-time use throw-away thing. Then can even iterate through only once. They are not "updated" by the engine when components change or so. "Live filtering" is just so fast (check mask once per archetype) that this is not necessary.

Yeah, works to remove the reflect from the pools, for the columns in the archetype I think you'll need to drop the client's component ids in favor of search by type internally. Don't know if worth the extra work, only if you think in terms of security, as you remove the potential error of casting to a type and passing the component id of another.

Ah, a small addition: Query is a one-time use throw-away thing. They can even iterate through only once. They are not "updated" by the engine when components change or so. "Live filtering" is just so fast (check mask once per archetype) that this is not necessary.

Nice. I'll compare this against the filters in the long run adding/removing entities/components

for the columns in the archetype I think you'll need to drop the client's component ids in favor of search by type internally

I don't understand this. Exactly for the type safety, I would prefer such an approach. But I don't see how this could work.

Used the resulting thoughts to implement generics for safety on top of the ID-based stuff, like this:
// Q2 is a generic query for two components
type Q2[A any, B any] struct {
	Query
	ids [2]ID
}

// Query2 creates a generic query for two components
func Query2[A any, B any](w *World) Q2[A, B] {
	ids := [2]ID{ComponentID[A](w), ComponentID[B](w)}
	return Q2[A, B]{
		Query: w.Query(ids[:]...),
		ids:   ids,
	}
}

// Get returns all queried component for the current query position
func (q *Q2[A, B]) GetAll() (*A, *B) {
	return (*A)(q.Query.Get(q.ids[0])), (*B)(q.Query.Get(q.ids[1]))
}

// Get returns the first queried component for the current query position
func (q *Q2[A, B]) Get1() *A {
	return (*A)(q.Query.Get(q.ids[0]))
}

// Get returns the second queried component for the current query position
func (q *Q2[A, B]) Get2() *B {
	return (*B)(q.Query.Get(q.ids[1]))
}

Quite a lot of boilerplate with Q1, Q2, ... Q8 though, and similar for adding and removing components (up to 5).
Getting components this way outside of queries is too slow to use in hot loops. For queries, however, the overhead of looking up type IDs is only payed at creation, so no problem there.
Definitely better user experience and way more safety.

Hello @mlange-42, I was a bit busy last week so now I'm looking at the issues. From our conversation, I decided to remodel the package, giving the archetype a go, but with a little different approch than yours.
In a few days I may put the code online, but basically I'm thinking of usability for the users of the package. The user will see something like this (maybe this gives you a few ideas):
	world := NewWorld()
	// number of threads to execute the loop of searches
	world.SetParallel(4)

	// Entity is a suggar wrapper for the EntityID, with helper functions
	// to add, remove and create relations with other entities.
	camera := world.NewEntity()
	player := world.NewEntity()
	level := world.NewEntity()
	inventory := world.NewEntity()

	// Add adds the components to the entity, and register the component if its not already in the list
	level.Add(NewTileSet("tileset.map1"))
		.Add(&TileSetCollider{})

	camera.Add(&Camera2D{ zoom: 40, fovY: 40.0 / 25.0  })
		.Add(&Follow{ entity: player })
		.ChildOf(level.EntityID)

	// Next step is to create something like "batch add" to reduce the stress on archetypes
	player.Add(&PlayerControlled{})
		.Add(&Vec3{ 0, 0, 0 })
		.Add(&Rotation{ 0.0 })
		.Add(&BoxCollider{})
		.Add(&Energy{ total: 100, actual: 100 })
		.Add(&Mana{ total: 0, actual: 0 })
		.Add(NewAnimation("player.anim"))
		.Add(&AnimationPlayer{ state: "idle" })
		.ChildOf(level.EntityID)

	inventory.ChildOf(e.EntityID)
		.Add(&Inventory{})

	allControlledEntities = []EntityID{
		w.ComponentID(&Vec3{})
		w.ComponentID(&Rotation{}),
		w.ComponentID(&PlayerControlled{}),
	}

	allAnimatedEntities = []EntityID {
		w.ComponentID(&AnimationStateMachine{})
		w.ComponentID(&AnimationPlayer{})
	}

	w.Lock()
	w.Each(allControlledEntities, func (entityID EntityID, vec, rot, _ unsafe.Pointer) {
		//
	})

	// EachParallel runs async and subdivides the calls in batches to speed up the proccess
	w.EachParallel(allAnimatedEntities, func(entityID EntityID, animFSM, animPlayer unsafe.Pointer) {
		//
	})
	w.Each(allFollowCameras, func(entityID EntityID, camView, follow unsafe.Pointer) {
		//
	})

	// Unlock already wait for async iterations
	w.Unlock()

As you said, accessing the Components outside of filters/query/iterators is a little slow, but I think there's some techniques that can be used to mitigate this (LRU, simpler hashmaps, etc). In anycase, this is a wrapper for the boilerplate to create and register components in the world (using Entity wrapper instead of manually using EntityID in calls to the world).
Let me know what you think

Forgot to mention, this new approach is not limited to 64 components, I plan to create some more complex examples using a lot of components and interactions to test this idea. I'm doing some benchmarks to see if I'm better using a custom hashmap than the Go's map

Wow, that's quite a lot of new stuff to think about. A few loose thoughts...

Not sure if using the entity wrapper is so helpful. Each entity needs a reference to the world I think, which is highly redundant.
Regarding the closure for iteration... it will always get all components, which may not be required by the system.
For registering and getting component IDs, you could use a generic function that takes the world as argument, like ComponentID[Camery2D](&world).
The world should probably not be locked for the full time step/over multiple systems. This might cause unexpected effects if e.g. an entity that was removed by one system it nevertheless considered alive by a later system.

Regarding speed of access via entity ID, I think there is not much that can be improved, particularly a map would not help. It is already based on plain array indexing. And we are talking about like 1-2ns of difference, so not too much.
Regarding general usability, this is also what I am mostly working on currently. The inner working of the world as well as it's API are mostly set. What I did then is to build a safer generic way of access in a separate package (i.e. on top of the core package), as well as logic filters in yet another package.
It all works quite well with the world API, and could even be implemented by a user as the core does not know about it. This taught me that it works very well to see the world as just a data store and nothing more, and build the rest around it (or let users do it).
Regarding the 64 limits... implemented a 128 bit bitmask, which should be enough for my use cases: ecs/bitmask.go.
In case you take a look at my project again, be aware that the docs on pkg.go.dev are completely outdated regarding the generics stuff, compared to the main branch.

BTW: The method chaining for adding components is cool. For batching, you could use the builder pattern and add a final .Build() or .Apply() call.
What I am a bit in doubt about is the child thing. Is it really useful to code that into the engine? I think users should do this using components. Also, there might be more than one hierarchy, or other relations than parent and child. If you think games will have a scene graph, I might make sense however.

Not sure if using the entity wrapper is so helpful. Each entity needs a reference to the world I think, which is highly redundant.

Yes, will need a ref to world but it'll wrap a lot of boilerplate. This is an optional struct and just useful to insert the entities in the world in a more intuitive way. The goal is to have a simple way to create and define the entities, but not keep it for long, just when necessary.

The world should probably not be locked for the full time step/over multiple systems. This might cause unexpected effects if e.g. an entity that was removed by one system it nevertheless considered alive by a later system.

Good point. Maybe a more internal lock mechanism would suffice for the parallel loop.

Regarding general usability, this is also what I am mostly working on currently. The inner working of the world as well as it's API are mostly set. What I did then is to build a safer generic way of access in a separate package (i.e. on top of the core package), as well as logic filters in yet another package.

I'm trying to keep some small use of reflect here and there to not fully commit with generics. From my tests for the storage, using reflect or generics gives the same results. On top of that, we can't use generics in functions from interfaces, and that's a shame... would resolve all the problems but hey, if I want it so bad maybe I need to go back to C++ :smile:

BTW: The method chaining for adding components is cool. For batching, you could use the builder pattern and add a final .Build() or .Apply() call.

Yes, I though about that, using the builder pattern always would be simpler and faster than insert one by one

What I am a bit in doubt about is the child thing. Is it really useful to code that into the engine? I think users should do this using components. Also, there might be more than one hierarchy, or other relations than parent and child. If you think games will have a scene graph, I might make sense however.

The way I did I can have multiple parents, it makes sense if the user fully commit with ecs to manage all the data. There's some interesting usecases, like for example, filtering all children of entity that have xyz components. I'll think more about it, because it's easy to create a component "Parent" that have the parent ID, but then how can I filter for a specific parent?
Maybe it would be easier to serialize all the data with relationships, as that is what I'm planning to do next.

This is an optional struct and just useful to insert the entities in the world in a more intuitive way. The goal is to have a simple way to create and define the entities, but not keep it for long, just when necessary.

So it is generated on the fly when getting the entity? (or not, if you want the plain entity...). All doubts cleared...

Good point. Maybe a more internal lock mechanism would suffice for the parallel loop.

My query iterator locks the world when created from a Filter, and unlocks when Next is false the first time (i.e. loop ends). For breaking out of the loop manually, it has a Close() method.
Should be even simpler with closures for iteration.
Thought about it, but I will probaly not provide an engine-side way to delay operations until the world is unlocked. Users can do it more optimal for their use case, and it is more transparent and direct IMO. But that's owed to the scientific purpose and also just personal preference.
BTW... not sure how you plan to have it, but it is probably wise to not restrict a system to a single query (i.e. make it a pure closure). I had several cases where I wanted to iterate multiple queries in one system.

I'm trying to keep some small use of reflect here and there to not fully commit with generics.

I still think generic storage does not work with archetypes (unpredictable type combinations).
I use reflection only outside the World (except for ComponentID[T](*World) and the stuff behind).
For the rest, reflection is only used when constructing queries etc. That's done once, or (in rare cases) once per time step. It gets "translated" into IDs or bitmasks, which are then used in iteration etc.

On top of that, we can't use generics in functions from interfaces

I really hope Go gets generic methods some time in the future. Really struggling to design the best generic API (on top/as a wrapper) given that things like these are required:

faster than insert one by one

Insering one by one will be a performance killer for an archatype ECS. I even provide ways to add and remove multiple components in one go (Exchange()).
With the builder pattern, that would be much easier and simpler than the multiple-generics-way I am currently using. If only generic methods were possible... generic builder pattern... Only possible with weird nested generic functions syntax now. Won't do that...

There's some interesting usecases, like for example, filtering all children of entity that have xyz components.

I can currently not really imagine how the engine could help here.
My idea would be to provide a way to iterate through a list of entities (provided by the user, e.g. taken from the Children field on a component). In a way that the usual kind of filter is applied. Well, the user could also just do the loop and check "manually"...
Checking the composition of an entitiy (or presence of a component) is quite cheap. You only need to check the archetype's mask, no need to visit the content for the entity.
I provide a way to get the full component mask for an entity (from the world or in a query [faster]), for the user to do fast checks. Could be something manual, or using Filter (interface, logic filters).
I think (with my limited knowledge) that you can't optimize a lot regarding entity relations by handing things to the engine. Given the assumption of an AB ECS, the entities sought after here will not be aligned in memory anyway.

Yeah, I understand why they don't want to go full yolo with generics, but it's ugly to do those things manually.
The way I manage components is with a "component storage factory". With generics, it's something like this:
type Component struct {
	EntityID
	reflect.Type
	NewStorage func() Storage
}

func NewComponentRegistry[T any](ep EntityPool) *Component {
	var t T
	return &Component{
		ep.NewComponent(),
		reflect.TypeOf(t),
		func() Storage {
			return NewStorage[T](0, 0)
		},
	}
}

I can register this component in the factory and instantiate a correct Storage from the type or ID.
Notice that the reflection can be removed if we don't want things like registry.GetByType(ComponentType{}).
I'm doing this way just because the generic Storage is 10x simpler than the reflected one, and when instantiating the
component Storage, there's no reflect involved whatsoever.
Don't know how you're storing the components ids, but I choose to use the "EntityPool" to store entity and component IDs.
My entityID is a uint64 with some bits for flags to control if the id is an entity or a component, and if it's a component, if it is a singleton. Something like this:
[32           | 24         | 8    ]
[Identifier   | Generation | Flags]

My Entity is currntly a uint32 for the ID and a uint16 for the generation, in a struct. See here.
So there are still 16 bits free space, and I may rework it to be a uint64.
Regarding generics, I still don't get it. I have to create archetypes on the fly from a bitmask or list of IDs, so no ...[T] possible I think. Would be happy to use it instead of the reflect buffer stuff, but I just don't get it.

My Entity is currntly a uint32 for the ID and a uint16 for the generation, in a struct. See here.
So there are still 16 bits free space, and I may rework it to be a uint64.

Indeed, the main reason I used a uint64 is that maps with uint64 as key are very fast to access.

Regarding generics, I still don't get it. I have to create archetypes on the fly from a bitmask or list of IDs, so no ...[T] possible I think. Would be happy to use it instead of the reflect buffer stuff, but I just don't get it.

I saw the code, but didn't take a deep look in the internals. I don't know if I understand correctly what you think that don't work for create the components on the fly. Maybe is the need to put generics from the New call all the way to the Storage creation?
What I did to remove this coupling is to create an interface for Storage, and the implementation is generic. When I register the component (using generics), I return a function that internally uses the generic storage creation, like this:
 return func() Storage {
     return NewStorage[T]()
 }

With this I can lookup the component by reflect.Type or ID, and use this simple function to create the correct Storage. No need for generics in any other step. My english is very rusty, so maybe all will become understandable when I upload the source.

Hello @mlange-42
I updated the source code of the project with the new architecture I worked on.
This is a wip, as it's missing the world. entity wrapper and iterators, but the fundamentals are almost in place.
I could not benchmark your project, as I can't seem to include the filter package. I'm doing something wrong? The file is in the benchmark folder.
I'll keep this request open as I continue to improve and finish the implementation, so I'll do more extensive tests for singletons and close this request afterwards =)

Thanks for the info!
You should not need the filter package for the benchmarks. There is also All(ids...) in ecs (in the dev version).
Update Arche to v0.4.0-rc1 and it should work (and be faster in most departments).
Decided to try to slim down the API a bit more (#100). There will probably be a v0.4.0 release in the next weak, with these (and more) breaking changes.
Will take a look at your code the next days.

Being a bit sceptical about using interfaces in potentially performance-citical code, I gave it a try to "hide" my storage behind an interface. I observed a doubling of archetype indexing time (get comp. x for index i) from 1ns to 2ns. Which is quite substantial given that Get inside a query is currently between 1ns and 1.5ns for me. It would probably also not be outweighted by a potential speedup from not using reflect buffer (and it looks like there is no speedup to be expected).
Just to let you know about potential impacts...

Depending on the interface, if you implement and pass by pointer or by ref, can be a significantly increase in latency.
I saw this in the "Each()" idea of mine for the iterations. It would work really well if it was C/C++, but not in Golang. The biggest cycles eater in my tests are the array bounds check that Go automatically puts in, that's why the reflect value Storage is faster than a generic Storage (there's no array out of bounds in the unsafe pointer arithmetic).
The last few days I did very good progress in my new design, timming at 0,036ns vs 0,316ns from your version, still figuring out how to squeeze this last bits of performance, will update soon.
For me the biggest advantage of interfaces is to make clear the bigger picture of the project, with the definition of the methods and possibility of multiple implementations (ie. archetype graph for limited components and  unconstrained variants).
Just want to thank you for pointing me to the right direction, it's been a lot of fun and learning to revamp this package with new cool ideas =)

Looking at your (old) benchmarks and the numbers you write here, I am asking myself who of us is doing a wrong calculation. I get like 2500ns for iterating 1k entities and getting one component. I.e. 2.5 ns per iteration. Here, and in your old benchmarks, numbers are far lower all over the place. Things like BitMask.Get(id) are >0.3ns for me. Pure slice iteration is also in this order of magnitude per item. See e.g. here: https://github.com/mlange-42/arche/actions/runs/4225597459/jobs/7338078014

(if there is 1000 in the name, divide by 1000. ...Interface in the last line means it is a slice of interface{}, not that the storage is behind an interface)
So in case you managed to get the same speed as pure slice iteration, your numbers times 10 would fit.
Don't know how your benchmarks look like, but I found that you also need to actually do something with the retrieved component (as an example). Otherwise, the compiler might just optimize things away.
Keen to see how your seemingly super-fast solution looks like!

BTW, I released v0.4.0 today, which nails down the API.
Regarding interfaces, I would definitely also prefer to use them it there is a way to avoid the performance penalty.

BenchmarkArcheECS_1000_entities_10000_updates-4<PHONE_NUMBER>               0.03142 ns/op
BenchmarkEngoEngine_1000_entities_10000_updates-4<PHONE_NUMBER>               0.06861 ns/op
BenchmarkEntitas_1000_entities_10000_updates-4<PHONE_NUMBER>               0.2252 ns/op
BenchmarkEnto_1000_entities_10000_updates-4                    1<PHONE_NUMBER> ns/op
BenchmarkGameEngineECS_1000_entities_10000_updates-4<PHONE_NUMBER>               0.03547 ns/op
BenchmarkGecs_1000_entities_10000_updates-4<PHONE_NUMBER>               0.6334 ns/op
BenchmarkLecsGO_1000_entities_10000_updates-4<PHONE_NUMBER>               0.1341 ns/op
PASS
ok      github.com/marioolofo/go-gameengine-ecs/benchmark       30.214s

Btw, my implementation is a lot faster to insert data in the archetypes than yours, but is a little slow when filtering, I update the code, you can see the benchmark code in the benchmark folder.
goos: linux
goarch: amd64
pkg: github.com/marioolofo/go-gameengine-ecs/benchmark
cpu: Intel(R) Core(TM) i5-8300H CPU @ 2.30GHz
BenchmarkArcheECS_100000_entities_100_updates-4<PHONE_NUMBER>               0.6062 ns/op
BenchmarkGameEngineECS_100000_entities_100_updates-4<PHONE_NUMBER>               0.07197 ns/op
PASS
ok      github.com/marioolofo/go-gameengine-ecs/benchmark       21.979s

I found something very interesting benchmarking my last version (wip) and yours v0.4.0, give it a look:
$ go test -bench='.*(Engine|Arche)ECS_100_entities_10000_updates'
goos: linux
goarch: amd64
pkg: github.com/marioolofo/go-gameengine-ecs/benchmark
cpu: Intel(R) Core(TM) i5-8300H CPU @ 2.30GHz
BenchmarkArcheECS_100_entities_10000_updates-4<PHONE_NUMBER>               0.004095 ns/op
BenchmarkGameEngineECS_100_entities_10000_updates-4<PHONE_NUMBER>               0.003837 ns/op
PASS
ok      github.com/marioolofo/go-gameengine-ecs/benchmark       0.065s

$ go test -bench='.*(Engine|Arche)ECS_1000_entities_10000_updates'
goos: linux
goarch: amd64
pkg: github.com/marioolofo/go-gameengine-ecs/benchmark
cpu: Intel(R) Core(TM) i5-8300H CPU @ 2.30GHz
BenchmarkArcheECS_1000_entities_10000_updates-4<PHONE_NUMBER>               0.02952 ns/op
BenchmarkGameEngineECS_1000_entities_10000_updates-4<PHONE_NUMBER>               0.03540 ns/op
PASS
ok      github.com/marioolofo/go-gameengine-ecs/benchmark       0.528s

$ go test -bench='.*(Engine|Arche)ECS_10000_entities_10000_updates'
goos: linux
goarch: amd64
pkg: github.com/marioolofo/go-gameengine-ecs/benchmark
cpu: Intel(R) Core(TM) i5-8300H CPU @ 2.30GHz
BenchmarkArcheECS_10000_entities_10000_updates-4<PHONE_NUMBER>               0.2864 ns/op
BenchmarkGameEngineECS_10000_entities_10000_updates-4<PHONE_NUMBER>               0.3514 ns/op
PASS
ok      github.com/marioolofo/go-gameengine-ecs/benchmark       11.319s

$ go test -bench='.*(Engine|Arche)ECS_100000_entities_10000_updates'
goos: linux
goarch: amd64
pkg: github.com/marioolofo/go-gameengine-ecs/benchmark
cpu: Intel(R) Core(TM) i5-8300H CPU @ 2.30GHz
BenchmarkArcheECS_100000_entities_10000_updates-4                      1<PHONE_NUMBER> ns/op
BenchmarkGameEngineECS_100000_entities_10000_updates-4                 1<PHONE_NUMBER> ns/op
PASS
ok      github.com/marioolofo/go-gameengine-ecs/benchmark       7.080s

For 1k and 10k entities, your code is more performant, but mine is close in the extremes. This is what I said that I can't figure out whats going on :smile:

But still, how do you get these low numbers in general? It is increasing with the number of entities, so it looks like it is per "iterate over all", where numbers should be even higher. For me, this stuff looks like this:

Times are for iterating once over the given number of entities.
The last one is the classic pos/vel example, with 9k additional entities with only pos, no vel.

For the difference in adding entities, the Arche code could be made more efficient, by changing code like this:
e1 := world.NewEntity()
world.Add(e1, uidesignScriptComponents...)

to this:
e1 := world.NewEntity(uidesignScriptComponents...)

The first variant make one useless move between archetypes. So roughly, this should result in a speedup of 50%.
Further, something like this might also speed up initialization:
world := ecs.NewWorld(
    ecs.NewConfig().WithCapacityIncrement(1024)
)

(or even higher, but this should already be way faster then the default of 128).
The "problem" with arche here is that there is no paging of archetypes, so when capacity needs to increase, everything needs to be copied over into the new buffer.

Looking at your (old) benchmarks and the numbers you write here, I am asking myself who of us is doing a wrong calculation. I get like 2500ns for iterating 1k entities and getting one component. I.e. 2.5 ns per iteration. Here, and in your old benchmarks, numbers are far lower all over the place

Maybe one difference is the testing.B.N ?
Some packages crash the benchmark when iterating with this, for this reason I created the tests with names xx_entities_yy_iterations
So the iterations are fixed for the given test, maybe this is the difference, or the OS?
My machine is a Dell G3 with i5 8300H 16GB
I'm using OpenSUSE Leap 15.4 with Go 1.21 compiled from source.
I can do a checkout of your project and benchmark here if you like.

the difference in adding entities, the Arche code could be made more efficient, by changing code like this:

Changed to never have to reallocate entities and the call to NewEntity, solved the "problem", now it's very fast

Hello @mlange-42
I think I'm done with the refactor, the difference between our implementations now resides in the way we define the size of memory allocations.
I'll now add the singleton components (basically I'll implement a storage that return the same value for any row, and
make the component registry return the same instance for every call to NewStorage).
Tag components already works in this version, so nothing more to be done in this case.
So I think I'm done with this ticket, if you want to continue sharing some ideas, feel free to open another discussion or reach me by email.

Thank you for the very enlightning conversation! Will take another look at your code later.

You're welcome.
Finished the singleton component, I'll close this for now, but anything you need, just ask


Add check for fzf splits

fzf is a fuzzy finder that can be used from within vim or from the shell. It uses Ctrl-K and Ctrl-J by default to navigate up and down the list, but because fzf opens up in a tmux split, these bindings conflict with the bindings of vim-tmux-navigator.
I was wondering if vim-tmux-navigator could check if a tmux split is running fzf (if not by default, I would appreciate if someone could tell me how to modify .tmux.conf to achieve this), and if that's the case pass the keys to fzf rather than switching panes.

Hello @hanschen, thanks for the question. I'm a user (and big fan!) of fzf, but I don't run into this issue as I use the C-n/C-p bindings to move up and down the fzf list, leaving C-j/C-k open for pane navigation. I'd suggest giving this a try as C-n and C-p are very common "next", "previous" mappings and could serve you well in other apps, and solve this immediate issue.
That said, I did take a look to see it would be possible to extend the mappings in tmux-navigator to special case fzf and unfortunately it doesn't seem possible. The reason is that when fzf (specifically the fzf-tmux command) is running, the pane_current_command is listed as the parent shell (zsh or bash). Not suer why this is, but it means that we are unable to detect fzf running, at least via the current method using pane_current_command, will not work.
Sorry we don't have a better answer here, but hopefully you can make due with C-n/C-p.

Thanks for the suggestion and for looking into this, @christoomey! I guess I'm used to C-j/C-k from ctrlp, but I should be able to get accustomed to C-n/C-p in time.
Thank you for your great work with vim-tmux-navigator!


nextcloud24: init at 24.0.0

Description of changes
Added Nextcloud 23 and set it as the default Nextcloud version for the
NixOS module. Added PHP 8.1 as an option for phpPackage and default for
Nextcloud ≥ 24.
Things done

Built on platform(s)

[x] x86_64-linux
[ ] aarch64-linux
[ ] x86_64-darwin
[ ] aarch64-darwin

[ ] For non-Linux: Is sandbox = true set in nix.conf? (See Nix manual)
[ ] Tested, as applicable:

NixOS test(s) (look inside nixos/tests)
and/or package tests
or, for functions and "core" functionality, tests in lib/tests or pkgs/test
made sure NixOS tests are linked to the relevant packages

[x] Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
[ ] Tested basic functionality of all binary files (usually in ./result/bin/)
22.05 Release Notes (or backporting 21.11 Release notes)

[ ] (Package updates) Added a release notes entry if the change is major or breaking
[ ] (Module updates) Added a release notes entry if the change is significant
[ ] (Module addition) Added a release notes entry if adding a new NixOS module
[ ] (Release notes changes) Ran nixos/doc/manual/md-to-db.sh to update generated release notes

[x] Fits CONTRIBUTING.md.

An eval-warning for Nextcloud 23 would be now needed. I'm happy to implement this, but I won't make it before the weekend.

Do you mean 22?  23 should still be supported by upstream for a while longer.

Is it safe to upgrade from 23 to 24 ? Like won't the database schema for Nextcloud be changed and rolling back using generation on NixOS would still fail, should backups be made before ?

Yes it usually is on major changes.

Thanks, @Ma27, so it is usually safe, but making a backup of some of the databases I guess isn't bad practice, just in case, but so far I've never had any major upgrade break on me as long as I go from one major to another consecutive major version, like going from Nextcloud18 to Nextcloud24 would be breaking things but from 23 to 24 would be alright.

Nextcloud would refuse to go straight from e.g. 18 to 24.
Btw, busy weekend, please be a bit patient with me, will try to take care of getting this ready this week.

Oh, I wasn't aware that Nextcloud would refuse to do so, no worries on time for this PR, I won't be upgrading my instance any time soon this coming week, take all the time you need.

I have never had luck downgrading nextcloud, even for minor versions; their docs recommend backup as the only rollback strategy.

An eval-warning for Nextcloud 23 would be now needed. I'm happy to implement this, but I won't make it before the weekend.

I am unclear on the reason for the eval-warning, but if you mean the one for nextcloud21 in default.nix, that is there due to end of life. As such, @aidalgol is correct in stating that you meant 22, not 32, but even then 22 is not yet eol, see the upstream support matrix. I would rather wait until july to execute that change.

@Ma27, I am unclear on the reason for the eval-warning, but if you mean the one for nextcloud21 in default.nix, that is there due to end of life. As such, @aidalgol is correct in stating that you meant 22, not 32, but even then 22 is not yet eol, see the upstream support matrix. I would rather wait until july to execute that change.

Heh, now I see our misunderstanding :)
I meant the change I did in e46bff9 .
Still, we should drop nextcloud22 rather soonish (i.e. before 22.05, otherwise we'll have EOLed software in 22.05 which is supported until the end of 2022).

@arnottcr thanks! Going to backport nextcloud24 (without the breaking changes such as changed efaults) to 21.11 later today.

already started that in #173094; feel free to polish and merge

Oh, very nice, thanks a lot! :)

After a few attempts at fixing this:

setting nextcloud.phpPackage = pkgs.php80; works, although I had to remove the twofactor_totp app and reinstall it manually
manually editing /var/lib/nextcloud/store-apps/twofactor_totp/appinfo/info.xml and bumping the maximum supported php version to 8.1 also works

Oof Nextcloud again :(
I assume that the issue occurred because you already deployed PHP 8.1 and thus the app was marked as broken. Because of that we should make PHP 8.0 the default for each Nextcloud until this issue is fixed.
@alarsyo do you want to file a PR for that? :)

you can always use nixtcloud24 with php80 via phpPackage


refactor: format w. black/isort, some comments + renaming of function

Thanks for a great review! I ended up incorporating the streaming AND term search - much nicer way to load and search files!!
I actually ended up removing the ability to start the process where "you left off" since:

It kept breaking whenever I made changes (over-writing files etc.)
It overcomplicated the code (since I have to take into account what happens if you interrupt mid-file)
Not worth it when processing all files takes only 30 mins lol

If you run the script again, it will therefore DELETE the file and create a new one (to avoid duplicates since I'm appending). To avoid accidentally deleting data if running the code at a later time, I have made the save_path folder specific to the date (Y-m-d). Not sure if this is the best way to approach.

Merging this now! Have implemented --out_path instead of --save_path and save_file.open() instead of .unlink(), but making no default save path.


0.0001 to power 2

This calculation takes a long time.

I changed the square root code to use the more standard Newton's formula and it now works better.

Please enlighten me with your source code modifications :-)

The code is at the end of this comment. It seems to be better at small values of N.
There's some of my debug code in there too, and it's untidy, I'm working on getting this all running on my calculator PCB. I have code that runs on a RP Pico, if you have one of those then I could send you the firmware file so you can run it. It is a simulation of the Casio PRO-101. It's pretty much finished, I just have some bugs to sort out and tidying up.
// Icd::sqrt
// Description:   Square root of the number
// What it does:  Does an estimation through a double and then
//                Uses the Newton estimation to calculate the root
icd
icd::SquareRoot() const
{
icd number(0L,0L);
icd half(("0.5"));
icd two(2L);
icd three(3L);
int sqrti = 0;
// Optimization: sqrt(0) = 0
if(IsNull())
{
return number;
}
#if DEBUG_SQRT
printf("\nSQRT:Number:%s", number.AsString().c_str());
#endif
// Getting the breaking criterion
icd epsilon = Epsilon(10);
number = *this; // Number to get the square-root from
if(number.GetSign() == -1)
{
throw new std::string(("Cannot calculate a square-root from a negative number"));
}
#if DEBUG_SQRT
printf("\nNumber now:%s", number.AsString().c_str());
#endif
// First estimate
double estimate1 = number.AsDouble() / 2;
double estimate2 = 1 / sqrt(estimate1);
icd result(estimate1);
icd between;
// Newton's iteration
icd last_result("0.0");
while(true)
{
result = (result + number/ result ) / two;
between = last_result - result;
if( between.AbsoluteValue() < epsilon)
{
break;
}
  last_result = result;

#if DEBUG_SQRT
printf("\nNumber now:%s", number.AsString().c_str());
printf("\nBetween:   %s", between.AsString().c_str());
printf("\nResult:    %s", result.AsString().c_str());
#endif
}

return result;
}

Tried out your alternate logarithm on the bcd class (see last checkin).
Sadly it performs much slower than the standard algorithm (some 14 times slower)
See Unitest in "UnitTestBCD.cpp testmethod "T100_Root10thousands" for a measurement and proof.
By the provided testcode i smell that you meant not to use the "bcd" class (which is the purpose of this project!) but the "icd" class.
Will provide an "icd200" test class as well. Stay tuned.

Ah, yes, I am using the ICD library not the BCD one. I have also ported it to a RP Pico. If you have access to a Pico then you can run that code, all you need is a Pico and a USB cable. I can give you access to that repository. It definitely ran slowly on the Pico port, and the alternative algorithm runs faster, at least for small numbers.
Have you tried testing with the value 0.00001?
that was the problem value for my port.
Andrew

Alas,
I have added the same unit tests for the ICD class and alsoo created a new ICD208 class with 104 decimals to meet your case.
For both classes all unit tests are added and your test case is added as an alternative square-root calculation.
The square root test are repeated a 1000 times in a tight loop with an HighPerformanceCounter around it.
The HPFCounter can measure in the nanosecond range.
These are the results for ICD: (See the unit tests)
For large numbers in ICD
Original code  : Speed of the SQUARE ROOT calculation = 0.161931
FAST SQUAREROOT: Speed of the SQUARE ROOT calculation = 0.641662
For small numbers < 1 in ICD (tested with 0.0001)
Original code  : Speed of the SQUARE ROOT calculation = 0.011214
FAST SQUAREROOT: Speed of the SQUARE ROOT calculation = 0.262210
For large numbers in ICD208
Original code  : Speed of the SQUARE ROOT calculation = 0.464387
FAST SQUAREROOT: Speed of the SQUARE ROOT calculation = 3.015204
For small numbers < 1 in ICD208 (tested also with 0.0001)
Original code  : Speed of the SQUARE ROOT calculation = 0.041188
FAST SQUAREROOT: Speed of the SQUARE ROOT calculation = 1.370566
CONCLUSIION:
No. Your alternative is a factor 4 to 25 times SLOWER than the original. That also counts in the range between 1 and 0.
The evidence is in the unit tests for this.
Sorry.

That's really odd. I can video the two routines and how long it takes (I
only have the code running on real hardware).  I wonder if the Pico handles
some aspect of the calculation differently to the PC (x86?)?
It's not a problem as I can continue to run the code that is faster on the
Pico. This wasn't a criticism of your code, just that it seems to run
differently on the Pico.
The crashing at 200 digits is equally odd. I suspect some aspect of the
Pico again, as I have examined the code and can't quite see why it would
fail. For now, again, it's not a problem as 38 digits is fine for the
calculator simulator I am creating. For other calculator simulations I want
to do I would like 200 digits so I can do the standard 1E+/-99 number range.
Regards
Andrew Menadue
On Sat, 16 Dec 2023 at 16:22, Edwig Huisman @.***>
wrote:

Alas,
I have added the same unit tests for the ICD class and alsoo created a new
ICD208 class with 104 decimals to meet your case.
For both classes all unit tests are added and your test case is added as
an alternative square-root calculation.
The square root test are repeated a 1000 times in a tight loop with an
HighPerformanceCounter around it.
The HPFCounter can measure in the nanosecond range.
These are the results for ICD: (See the unit tests)
For large numbers in ICD
Original code : Speed of the SQUARE ROOT calculation = 0.161931
FAST SQUAREROOT: Speed of the SQUARE ROOT calculation = 0.641662
For small numbers < 1 in ICD (tested with 0.0001)
Original code : Speed of the SQUARE ROOT calculation = 0.011214
FAST SQUAREROOT: Speed of the SQUARE ROOT calculation = 0.262210
For large numbers in ICD208
Original code : Speed of the SQUARE ROOT calculation = 0.464387
FAST SQUAREROOT: Speed of the SQUARE ROOT calculation = 3.015204
For small numbers < 1 in ICD208 (tested also with 0.0001)
Original code : Speed of the SQUARE ROOT calculation = 0.041188
FAST SQUAREROOT: Speed of the SQUARE ROOT calculation = 1.370566
CONCLUSIION:
No. Your alternative is a factor 4 to 25 times SLOWER than the original.
That also counts in the range between 1 and 0.
The evidence is in the unit tests for this.
Sorry.
—
Reply to this email directly, view it on GitHub
https://github.com/edwig/BCD/issues/11#issuecomment-1858859495, or
unsubscribe
https://github.com/notifications/unsubscribe-auth/AHQ75GEEGJZYMRH4NM27KETYJXDCVAVCNFSM6AAAAABAKUNKVOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNJYHA2TSNBZGU
.
You are receiving this because you authored the thread.Message ID:
@.***>

Hi,
I've had another look at this and the sqrt of 0.001 doesn't ever exit.
I've instrumented the code:
// Newton's iteration
// Un = U(3-VU^2)/2
while(true)
{
between  = number * result * result;  // VU^2
between  = three - between;           // 3-VU^2
between *= half;                      // (3-VU^2)/2
if(between.ValueBehindPoint() < epsilon)
{
  break;
}
result *= between;

#if DEBUG_SQRT
printf("\nNumber now:%s", number.AsString().c_str());
printf("\nBetween:   %s", between.AsString().c_str());
printf("\nResult:    %s", result.AsString().c_str());
#endif
And I get this repeated on the output:
Between:   +0.9999999999999999999999999999999999999998
Result:    +31.6227766016837933199889354443271853371996
Number now:+0.0010000000000000000000000000000000000000
Between:   +1.0000000000000000000000000000000000000014
Result:    +31.6227766016837933199889354443271853372438
Number now:+0.0010000000000000000000000000000000000000
Between:   +0.9999999999999999999999999999999999999992
Result:    +31.6227766016837933199889354443271853372185
Number now:+0.0010000000000000000000000000000000000000
Between:   +0.9999999999999999999999999999999999999996
Result:    +31.6227766016837933199889354443271853372058
Number now:+0.0010000000000000000000000000000000000000
Between:   +0.9999999999999999999999999999999999999998
Result:    +31.6227766016837933199889354443271853371994
Number now:+0.0010000000000000000000000000000000000000
Between:   +1.0000000000000000000000000000000000000014
Result:    +31.6227766016837933199889354443271853372436
Number now:+0.0010000000000000000000000000000000000000
Between:   +0.9999999999999999999999999999999999999992
Result:    +31.6227766016837933199889354443271853372183
Number now:+0.0010000000000000000000000000000000000000
Between:   +0.9999999999999999999999999999999999999996
Result:    +31.6227766016837933199889354443271853372056
Number now:+0.0010000000000000000000000000000000000000
Between:   +0.9999999999999999999999999999999999999998
I think the algorithm should exit on the ....9998 as epsilon is 2? maybe?
Your code is indeed faster than mine, I have timed 1.0, 0.1, 0.01,
but on 0.001 my ode exits and the original doesn't.
I'll investigate further.

I changed the code to this:
// Newton's iteration
// Un = U(3-VU^2)/2
while(true)
{
between  = number * result * result;  // VU^2
between  = three - between;           // 3-VU^2
between *= half;                      // (3-VU^2)/2
if( between < 1.0)
  {
between = 1.0-between;
  }

if(between.ValueBehindPoint() < epsilon)
{
  break;
}
result *= between;

#if DEBUG_SQRT
printf("\nNumber now:%s", number.AsString().c_str());
printf("\nBetween:   %s", between.AsString().c_str());
printf("\nResult:    %s", result.AsString().c_str());
#endif
I'm not sure if this is correct, but the loop now ends. the outputs I get are this:
Modified original code:
Square root
+1.0000000000000000000000000000000000000000

Started timing...
Elapsed time = 758us
sqrt=+1.0000000000000000000000000000000000000000
+0.1000000000000000000000000000000000000000
Started timing...
Elapsed time = 1711us
sqrt=+0.3162277660168379331998893544432718533719
+0.0100000000000000000000000000000000000000
Started timing...
Elapsed time = 980us
sqrt=+0.1000000000000000000000000000000000000000
+0.0010000000000000000000000000000000000000
Started timing...
Elapsed time = 34947us
sqrt=+0.0316227766016837933199889354443271853372
S
Newton method code (mine):
Square root
+1.0000000000000000000000000000000000000000

Started timing...
Elapsed time = 9477us
sqrt=+1.0000000000000000000000000000000000000000
+0.1000000000000000000000000000000000000000
Started timing...
Elapsed time = 10712us
sqrt=+0.3162277660168379331998893544432718533719
+0.0100000000000000000000000000000000000000
Started timing...
Elapsed time = 10249us
sqrt=+0.1000000000000000000000000000000000000000
+0.0010000000000000000000000000000000000000
Started timing...
Elapsed time = 14649us
sqrt=+0.0316227766016837933199889354443271853371
So the two methods give the same answers, your original code is faster except for 0.001, which was the problem case before. I'm not sure what is happening here, but the exit condition doesn't seem to work on the Pico the same way. I also think that an iteration is more expensive on the Pico than on the PC, probably because the PC CPU has a lot of extra hardware for arithmetic.
At the moment, I'd like to use your code as it is faster, mostly, but I don't trust my 'fix'.

This is certainly very odd as a Pico (mostly an Intel J4xxx processor) should handle integer arithmetics the same was as a regular 'large' Core-i processor (being it a i5, i7 or i9 processor). The ICD library was deliberatly designed to use only 'integer' arithmetic (hence it's name).
The main purpose was to handle financial calculations withou rounding errors as  'double' or 'real' datatypes would, and in the process NOT generate general ledger roundings where you should extra book a cent (0.01) to get your financial books in order.
So the purpose was NOT to make trigionometrics work. For that we offer AFP and BCD, which use a mantissa and are more suitable to handle logarithmics, trigionmics or other engineering calculations.
Most generally: The ICD class is used in production applications with never more than 2 decimals. And only for 'simple' financial calculations (add, subtract, multiply, divide)
So my advice to you would be that: willing and planning to build a calculator: you would be better off with the BCD class.
That said: neither of these - to my knowledge - have been previously tested on a pico....

It is indeed very odd. The Pico does have a hardware divider and the ARM
processor has a multiply but that's it I think for arithmetic acceleration.
I did look at your BCD libraray (and the Intel library, but that was way
too big) but the Pico has limited RAM. I can't remember why I chose the ICD
library instead. I didn't want to use malloc, maybe that was why, or maybe
it was too complicated to port.  I've nearly finished my calculator
simulator, which is of a Casio PRO-101, which is a financial calculator. So
the ICD library works for that. I think I'll look at the BCD library for
other calculators.
Do you think my 'fix' is correct? It works for a few test values, but I am
not 100% sure it's correct. I suppose using my slower square root works
fine for me.
Regards
Andrew Menadue
On Sun, 17 Dec 2023 at 11:56, Edwig Huisman @.***>
wrote:

This is certainly very odd as a Pico (mostly an Intel J4xxx processor)
should handle integer arithmetics the same was as a regular 'large' Core-i
processor (being it a i5, i7 or i9 processor). The ICD library was
deliberatly designed to use only 'integer' arithmetic (hence it's name).
The main purpose was to handle financial calculations withou rounding
errors as 'double' or 'real' datatypes would, and in the process NOT
generate general ledger roundings where you should extra book a cent (0.01)
to get your financial books in order.
So the purpose was NOT to make trigionometrics work. For that we offer AFP
and BCD, which use a mantissa and are more suitable to handle logarithmics,
trigionmics or other engineering calculations.
Most generally: The ICD class is used in production applications with
never more than 2 decimals. And only for 'simple' financial calculations
(add, subtract, multiply, divide)
So my advice to you would be that: willing and planning to build a
calculator: you would be better off with the BCD class.
That said: neither of these - to my knowledge - have been previously
tested on a pico....
—
Reply to this email directly, view it on GitHub
https://github.com/edwig/BCD/issues/11#issuecomment-1859149926, or
unsubscribe
https://github.com/notifications/unsubscribe-auth/AHQ75GBAWAHSVQBXJN46B5TYJ3MXPAVCNFSM6AAAAABAKUNKVOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNJZGE2DSOJSGY
.
You are receiving this because you authored the thread.Message ID:
@.***>


PoC - Static analyzer for determinism

I did a PoC of this at https://github.com/cretz/temporal-workflowcheck-java


Smt fix

Contains two soundness fixes for the SMT backend

@damiendoligez since this is causing a failing test can it be reverted so that the main branch has all tests pass in the CI? It can be merged again when it doesn't cause a test to fail.

It would be better to merge #98 instead of reverting this PR.


Update node-rdkafka to 0.8.0

The new version of of node-rdkafka has been released, and we need to update since it's bringing quite a few improvements and also might let us get rid of the memory leak we've been suffering from with the GuaranteedProducer. It depends on librdkafka 0.9.4 while we have version 0.9.1 installed on our servers. We need to make a joint coordinated update to all services.

Coverage decreased (-0.1%) to 85.971% when pulling c20b380d5da5dd9bc4114c524cc9f90b0087fbab on Pchelolo:driver0.8 into 56c6f9298a37ccc5e1b0aba4fe0912cd761061f2 on wikimedia:master.

Coverage decreased (-0.1%) to 85.971% when pulling c20b380d5da5dd9bc4114c524cc9f90b0087fbab on Pchelolo:driver0.8 into 56c6f9298a37ccc5e1b0aba4fe0912cd761061f2 on wikimedia:master.


user-profile: Change user profile layout

~* Fixed the user pofile layout bug when name is too long~

Changed to color of headers color

I merged the first commit.  For the second, I don't think we want to move the labels to their own line, at least for the long-paragraph description field types, and maybe for everything to ensure consistency.  We don't have handy examples of this, but the intent of that field type is that folks should be able to write a paragraph or two of text as part of an employee directory page within Zulip without it being compacted by the UI.

This is great, merged, thanks @SiddharthVarshney!


Is there proper way (or any ideas) not to send second copy of data via websockets?

When we use fast render, we have copy of our data injected into HTML. It provides faster overall response time for initial page load.
However, right after that 'real' subscriptions come through websockets, creating unnecessary load on meteor websocket connection.
In systems with low bandwidth capabilities (GSM connection to server) it may compromise whole connection (various timeouts come to play).
I wonder, how can I work around that and never send two copies of one object.
First, I thought it was simple: let's check in publication method if subscription is real and if it is instead of returning cursor use observeChanges to send events, skipping initial 'added' events because it was sent already as injected data.
Problem was that 'changed' and 'removed' events fail due to lack of initial 'added' event on server. Meteor caches every client's data on server and needs to have object already sent in order to send 'changed' or 'removed' event.
Now, I just send empty 'added' events. It leads to insignificant error on the client side (object already added), but works well.
However, I'm trying to find any way to not send initial data through websockets at all.
Can you guide me on how can I do that? I think that it could be nice improvement to fast-render packages and I'd love to work on PR.

Actually, this is harder than it seems to do it correct. If we are doing
this, it needs to be perfect and we don't need to loose data data.
Here's a one way to do it.

Cache fast-render docs on the server temporarly and create an ID
Then when the DDP connection is creating, send a that ID to the server
Then pick fast-rendered data to put them back to the mergeBox without
sending to the client
Then let subscriptions to work as normally

This can be done, but I'm not sure how exactly we can do it at this moment.
On Sun Feb 15 2015 at 6:15:15 PM Sergey Petrov<EMAIL_ADDRESS>wrote:

When we use fast render, we have copy of our data injected into HTML. It
provides faster overall response time for initial page load.
However, right after that 'real' subscriptions come through websockets,
creating unnecessary load on meteor websocket connection.
In systems with low bandwidth capabilities (GSM connection to server) it
may compromise whole connection (various timeouts come to play).
I wonder, how can I work around that and never send two copies of one
object.
First, I thought it was simple: let's check in publication method if
subscription is real and if it is instead of returning cursor use
observeChanges to send events, skipping initial 'added' events because it
was sent already as injected data.
Problem was that 'changed' and 'removed' events fail due to lack of
initial 'added' event on server. Meteor caches every client's data on
server and needs to have object already sent in order to send 'changed' or
'removed' event.
Now, I just send empty 'added' events. It leads to insignificant error on
the client side (object already added), but works well.
However, I'm trying to find any way to not send initial data through
websockets at all.
Can you guide me on how can I do that? I think that it could be nice
improvement to fast-render packages and I'd love to work on PR.
—
Reply to this email directly or view it on GitHub
https://github.com/meteorhacks/fast-render/issues/98.

+1


Inaccurate counting of mixed Chinese and English

Hi, when I write mixed Chinese and English in the note, the counting of novel-word-count is not accurate. For example:
hello 世界世界世界 hello hello

obsidian status bar:

novel-word-count:

The actual word count is 9 words, but novel-word-count report only 6.

For performance reasons, I've been counting each note as space-delimited or CJK, rather than trying to incorporate both into one RegEx. This is the first complaint I've had, but it doesn't look like it would be too difficult to combine them and possibly remove the setting to switch between them. I'll try it and see how it affects performance.

Please note, however, that the word count will likely never match up between Obsidian's status bar and Novel Word Count. See #38.

After some research, I'm going to say no to this one for now. Counts for mixed-language notes would require a much more advanced RegEx, versus the simple, fast, and easily understandable ones I use now. You'll have to decide which counting method you prefer.
At some point I may experiment with a custom lexer and see if it can keep up with String.prototype.match while also allowing higher logic than a RegEx, but no promises.

This has been fixed in v3.4.0. Mixed-language notes should now be counted correctly.


Disable the LED on the USB accelerator

Description
Is it possible to permanently disable the coral LED on the USB accelerator? The light can leak into images taken at night.
Thanks
Click to expand!
Issue Type
Feature Request
Operating System
Linux
Coral Device
USB Accelerator
Other Devices
No response
Programming Language
No response
Relevant Log Output
No response

I think, there is no way to disable it as we don't have any API for that (the LED is controlled by MCU firmware). Thanks!

Thanks for confirming, @hjonnala


Sync published with master

Proposed changes

Unreleased project version (optional)

Related issues (optional)

Deploy preview for docsdocker ready!
Built with commit d3afe5ed0dd676c0d3ed7c11f7db6a6efe74c6f6
https://deploy-preview-8474--docsdocker.netlify.com


Duplicate / invalid locale resolution on iOS

Steps to Reproduce
The issue is reproductible on iOS only.
Locale resolution works as expected on Android.

Create new flutter project
Implement localeListResolutionCallback
Observe duplicate locales

The following snippet shows the issue:
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Container(),
      supportedLocales: [Locale('en'), Locale('fr')],
      localeListResolutionCallback: (locales, supportedLocales) {
        debugPrint('Locales: $locales in $supportedLocales');
        if (locales.isEmpty) {
          return null;
        }

        for (var locale in locales) {
          if (supportedLocales.map((it) => it.languageCode).contains(locale.languageCode)) {
            return locale;
          }
        }

        return supportedLocales.first;
      },
    );
  }
}

Logs
English language only

Logs:
Locales: [] in [en, fr]
Locales: [en_CA, en_CA] in [en, fr]

Duplicated en_CA locale.
French, English languages

Logs:
Locales: [] in [en, fr]
Locales: [en_CA, fr_CA, en_CA] in [en, fr]

Duplicated en_CA locale, and always in the first position, while it should be fr_CA.
It breaks the localizations because the locale loaded is always en_CA.
Flutter doctor (I was also able to reproduce the issue on master)
[✓] Flutter (Channel stable, v1.7.8+hotfix.4, on Mac OS X 10.14.5 18F132, locale en-CA)
[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
[✓] Xcode - develop for iOS and macOS (Xcode 10.3)
[✓] iOS tools - develop for iOS devices
[!] Android Studio (version 3.4)
    ✗ Flutter plugin not installed; this adds Flutter specific functionality.
    ✗ Dart plugin not installed; this adds Dart specific functionality.
[✓] IntelliJ IDEA Ultimate Edition (version 2019.1.3)
[✓] VS Code (version 1.36.1)
[✓] Connected device (1 available)

https://github.com/flutter/engine/pull/18379 should fix this.

Duplicate of https://github.com/flutter/flutter/issues/49775, let's track it there!


How to get parameter from POST body?

To get YAML working in the editor, I had to put everything in a body parameter like this:
    parameters
        - name: body
          in: body
          required: true
          schema:
            properties:
              myParam:
                type: string

This implies that to access a post param in my controller, I have to do:
req.swagger.params.body.value.myParam
That is very cumbersome. Is that the only way to parse my POST body?

If you are passing a complex object ({"myParam": "foo"}, for example, that is indeed the right way to do this.

ok

I already have 3 hours reading about it, but it's not working at all. Need help!
My package.json
{   "name": "fomp-server",   "version": "0.0.1",   "private": true,   "description": "New Swagger API Project",   "keywords": [],   "author": "",   "license": "",   "main": "app.js",   "dependencies": {     "express": "^4.12.3",     "swagger-express-mw": "^0.7.0"   },   "devDependencies": {     "should": "^7.1.0",     "supertest": "^3.1.0",     "swagger-ui-express": "latest",     "yamljs": "^0.3.0"   },   "scripts": {     "start": "node app.js",     "test": "swagger project test"   } }
My Swagger
/signup/user:     x-swagger-router-controller: performSignup     post:       operationId: user       tags:       - signup       description: Attempts to register a user!!       parameters:       - name: body         in: body         schema:           $ref: "#/definitions/SignupRequest"       - $ref: "#/parameters/Channel"       - $ref: "#/parameters/Language"       responses:         200:           description: The user was logged in succesfully.           schema:             $ref: "#/definitions/MessageResponse"         400:           $ref: "#/responses/invalidInput"         503:           description: The platform is currently unavailable.           schema:             $ref: "#/definitions/MessageResponse"         409:           description: Cannot create session due to multiple session policy           schema:             $ref: "#/definitions/MessageResponse"
My controller performSignup.js
`function user(requ, res) {
try {
console.log(requ.swagger.params.body.username);
} catch (e) {
console.log(e);
}
try {
console.log(requ.swagger.params.body.username.value);
} catch (e) {
console.log(e);
}
try {
console.log(requ.swagger.body.username);
} catch (e) {
console.log(e);
}
try {
console.log(requ.swagger.body.username.value);
} catch (e) {
console.log(e);
}
try {
console.log(requ.body.username);
} catch (e) {
console.log(e);
}try {
console.log(requ.body.username.value);
} catch (e) {
console.log(e);
}
var response = {
"code": "OK",
"message": "User registered"
};
// this sends back a JSON response which is a single string
res.json(response);
}`
And still I don't get the value of my username!!!!

What an API, how can i simply get it as req.body.my_param_name.


FIX: TensorFlow version 2.11 compatibility issues

This fixes the error thrown when using TensorFlow 2.11 by setting the optimizer to the legacy version if TF 2.11 or greater is detected.

Thank you!   Gotta love tensorflow updates :)


Metrics plugin agent mode

Implement agent mode for the metrics plugin. This will be loaded into agent v2 to replace metrics-specific logic in agent v1.

There are now two main scheme definitions, gateway and agent, instead of just the one. This defines the set of plugin interfaces that the corresponding plugin loader will look for
The same plugin will have the capability to run in either agent mode or gateway mode
Agent/gateway mode will be controlled by the OPNI_PLUGIN_MODE env var which can be used in the plugin's main() to determine which plugin scheme to serve


Azure OpenAI support

Clear and concise description of the problem
It would be nice if Azure openai could be supported.
Suggested solution
Please refer to
https://learn.microsoft.com/en-us/azure/cognitive-services/openai/overview#comparing-azure-openai-and-openai
Alternative
No response
Additional context
No response
Validations

[X] Follow our Code of Conduct
[X] Read the Contributing Guide.
[X] Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.

sam as i

sam as i

You can already achive this now by using this method: haibbo/cf-openai-azure-proxy: A Cloudflare worker script to proxy OpenAI‘s request to Azure OpenAI Service

Yes, it could be awesome if the current project natively supports it.

After deploying, set the openai-azure proxy as the OPENAI_API_BASE_URL environment variable, and change the OPENAI_API_KEY to your Azure key.
Please note that you must deploy a proxy for every Azure model-type deployment.

After deploying, set the openai-azure proxy as the OPENAI_API_BASE_URL environment variable, and change the OPENAI_API_KEY to your Azure key.
Please note that you must deploy a proxy for every Azure model-type deployment.

it seem that OPENAI_API_BASE_URL is not working, my proxy works fine, but chatgpt-demo is still not working

After deploying, set the openai-azure proxy as the OPENAI_API_BASE_URL environment variable, and change the OPENAI_API_KEY to your Azure key.
Please note that you must deploy a proxy for every Azure model-type deployment.

thanks!


[Documentation Bug]: Missing Project Description and Potential README Improvements

Describe the bug ✍
Missing Project Description:
The current README file lacks a clear description of what Squard-line is and what it does.
Including a concise yet informative description would be beneficial for potential contributors and users who want to understand the project at a glance.
Potential Improvements:

Contribution Guidelines: In the "How to make a PR in a Project" section, a sentence at the beginning could clarify what kind of contributions are welcome (e.g. bug fixes, new features, documentation improvements).
Badges: The generic badges like "Built with love" could be replaced with more specific ones reflecting the technologies used (e.g. programming languages, frameworks).

Provide step by step information reproduce the bug 📄
Proposed Action:

I can draft a clear and concise project description based on the available information and update the contribution guidelines and badges section as stated above.

Please let me know if you'd like me to proceed with changes in Readme
Select program in which you are contributing
GSSoC24
Code of Conduct

[X] I follow CONTRIBUTING GUIDELINE of this project.

@Nidhi1314 go ahead


Add support for zwave-js 12.0 and schema 32

Follows https://github.com/zwave-js/zwave-js-server/pull/1036
Migration guide: https://zwave-js.github.io/node-zwave-js/#/getting-started/migrating-to-v12

Can we add tests for the non covered lines?

Once the PR linked above gets merged, I will refactor this one and add the missing coverage, we should be able to get this PR to 100%

Please mention the breaking changes in the client in the PR description.

Please mention the breaking changes in the client in the PR description.

You mean the fact that the FailedCommand exception parameters have changed?

No those haven't changed. We've removed properties and methods and added other ones to replace them regarding healing and changed a parameter in async_firmware_update_ota in the controller model.

No those haven't changed. We've removed properties and methods and added other ones to replace them regarding healing and changed a parameter in async_firmware_update_ota in the controller model.

ah thanks, thought we were talking about the client module 😅


Auto-detect deluge version?

I was thinking we could add a call to 'daemon.info' during the login process, before authenticating. It could catch the error on deluge 1.3, (daemon.info doesn't exist for that,) otherwise it gives the daemon version. This would mean the client could connect to either daemon version without user having to manually specify. I could test and make a PR if you like this idea.
Motivation: We are thinking about switching our deluge plugin in FlexGet to this library, and I'd prefer it worked without user having to specify our deluge version. https://github.com/Flexget/Flexget/pull/2102

Sounds great, I'll test your suggestion and try to get it working.

Hmm. I see what you mean about the timeout. If you send a deluge 1 formatted request to deluge 2, or vice versa, it never responds and just times out. Still trying to figure out if there is a good solution.

I believe I got this working, but it isn't so elegant as I first hoped. Not sure if it can be cleaned up further.

I think you'd have to make the client use non-blocking sockets to work around it and that seems like a lot of work to me for something I don't think the project really needs.
The only time I've hit the timeout problem has been while making mistakes during development and never in production.
If you solution works, then I'd happily accept it.


Was it abandoned?

Is this project not under maintenance, and is the update version?

https://github.com/querydsl/querydsl/issues/2170


file manager backend in BCDB & gevent

done on old code base digitalmeX needs to be migrated to new jumpscale


Don't print redundant errors when parsing GDScript (cherrypick to 3.x)

Just making the same change as https://github.com/godotengine/godot/pull/63317 to 3.x 😄
cc @akien-mga

Thanks!


feature: zoom-in / zoom-out cursor

To get some more orientation on the click behavior, it would be nice adding the zoom-in and zoom-out cursor to featherlight. Of course, it's just a few lines of css:
.zoom-in {
	cursor: -webkit-zoom-in;
	cursor: -moz-zoom-in;
	cursor: zoom-in;
}
.zoom-out {
	cursor: -webkit-zoom-out;
	cursor: -moz-zoom-out;
	cursor: zoom-out;
}

The more difficult part is the integration with the closeOnClick option ('background', 'anywhere', or false) the class allocation depends on. My javascript is not sufficient to make a pull req.
But maybe it would be an attractive little detail to add to featherlight.

I'm not exactly sure what you want to accomplish exactly, and I'm not sure you need any javascript.
Here's an example
In any case I doubt there's a need to add a special feature for something like this; featherlight is meant to be minimal and customizable after all.

thank you very much for the example, I'm really happy with it! Guess I thought way too complicated about it...


WIP: add warning for importing JSONio lib for matlab/octave

Regarding the issue #119
I am tempted to keep the original call to the function jsonwrite and simply add a warning if it fails with a link to the library.
Other possibility: call the bids.util.jsonencode function from the matlab-bids library which would also make sense because this is a bids related issue.
Any thought? @gllmflndn
Once we have decided I will change all the example scripts accordingly.

Also why is git / github showing ALL the lines as having been modified ?

Also why is git / github showing ALL the lines as having been modified ?

I think this is a windows line ending thing. I set this up when I install git....but it can be changed. Check out http://www.edwardthomson.com/blog/git_for_windows_line_endings.html for a longer discussion.

Thanks will have a look.
I was on windows and now back on linux (finally!!!) but pretty much copied my whole github/folder from there. So I suspect something is afoot there indeed.
Will get back to you when I have sorted this!

Closing this for now. Will reopen a new one once I have this line ending problem under control.


Registration Accessibility

Description
MA-2721
MA-2722
MA-2723
MA-2724
MA-2725
MA-2726
Fix for MA-2764
Accessibility issues on the registration screen have been implemented within this PR. Also, a fix for MA-2764 has been added in this PR.
Notes
Please refer to the Jira tickets for detailed description of the functionalities implements within this PR.
How to test this PR

Navigate to the Registration screen
Turn on accessibility
Make sure all components are reliant to the a11y standards

Reviewers
If you've been tagged for review, please check your corresponding box once you've given the :+1:.

[ ] Code review: @saeedbashir
[ ] Code review: @BenjiLee

Current coverage is 23.04% (diff: 76.74%)

Merging #806 into master will increase coverage by <.01%

@@             master       #806   diff @@
==========================================
  Files           678        678
  Lines         56418      56448    +30
  Methods           0          0
  Messages          0          0
  Branches          0          0
==========================================
+ Hits          13000      13011    +11
- Misses        43418      43437    +19
  Partials          0          0

Powered by Codecov. Last update d521417...7083088

[ ] MA-2721
[ ] MA-2722
[ ] MA-2723
[ ] MA-2724
[ ] MA-2725
[ ] MA-2726
[ ] MA-2764

@danialzahid94  This is out of scopish. Is there any way to dismiss the dropdown in VO mode?

@BenjiLee You are right. Currently the dismissing scenario is quite annoying. The current functionality for dismissing the dropdown doesn't work with VO. I'll look into this further to explore our options.

@danialzahid94 Let's consider this out of scope and get this PR merged. I would create a new ticket.

👍

Ready for another pass @saeedbashir

👍


How to create a mirror of official hub

In my work place, a lot of people use docker, and they pull the images from official registry.hub.docker.com site. I want to create a mirror so that these people can configure (add –registry-mirror=http://my_own_registry_mirror_site) to pull from my synchronized mirror.
I read the documentation and only find some useful link like https://docs.docker.com/reference/api/hub_registry_spec/, https://github.com/docker/distribution/blob/master/docs/deploying.md, however, I don't quite understand, can anyone show me some simple explanation about how to create a mirror of official hub.
Thanks in advance!

Hi!
Please read this important information about creating issues.
If you are reporting a new issue, make sure that we do not have any duplicates already open. You can ensure this by searching the issue list for this repository. If there is a duplicate, please close your issue and add a comment to the existing issue instead.
If you suspect your issue is a bug, please edit your issue description to include the BUG REPORT INFORMATION shown below. If you fail to provide this information within 7 days, we cannot debug your issue and will close it. We will, however, reopen it if you later provide the information.
This is an automated, informational response.
Thank you.
For more information about reporting issues, see https://github.com/docker/docker/blob/master/CONTRIBUTING.md#reporting-other-issues

BUG REPORT INFORMATION
Use the commands below to provide key information from your environment:
docker version:
docker info:
uname -a:
Provide additional environment details (AWS, VirtualBox, physical, etc.):
List the steps to reproduce the issue:
1.
2.
3.
Describe the results you received:
Describe the results you expected:
Provide additional info you think is important:
----------END REPORT ---------
#ENEEDMOREINFO

@liudonghua123 You should ask this on #docker-distribution on IRC, or in the docker-user mailing list. Since GH Issues isn't really a great forum for this kind of thing, I'm going to close this issue, but do please hop on IRC or docker-user to get some help with this.
Thanks!


Fix unit tests on Windows

On Windows, the resolution of SystemTime is 100ns, as opposed to 1ns on UNIX
(https://doc.rust-lang.org/std/time/struct.SystemTime.html#platform-specific-behavior).
As a result, any conversion of OscTime to SystemTime results in the
latter being quantized to the nearest 100ns (rounded down).
This also means both types of round-trips are lossy: for any time t,
t + i roundtrips to t for all 0ns <= i < 100ns.
Increase the tolerance for equality on Windows only
to 100ns instead of 5 to compensate for that, which in turn
makes the unit tests pass on Windows.

@maxnoel Thank you for your 2nd contribution 🎉!  I've no Windows machine available, so I'm pretty happy to receive a bugfix for this system.  Also, the good PR description is appreciated 😊


How to change timezone?

When creating backup, it uses GMT timezone to write the logs and filename. How to change the timezone to that of the current machine?

You can't really, but you can try this workaround https://github.com/backup/backup/issues/641#issuecomment-85688354


how do i get or set context path in SparkInstance ?

how do i get or set context path in SparkInstance ?

I assume your are not running int the embedded jetty server. AFAIK there is currently no way to get the context path in a Spark application.
I am working on a slightly modified version of spark which add a ServletContext parameter in the init method so I can get the context path while initializing my application. Maybe it would be less overkill to only provide the context path as a String to the SparkApplication init method. Either way it's a small patch that I can provide as a pull request if you're interested.
As for setting the context path I don't think that's even possible.

@MouettE-SC thank you


Is there an API method to change to a specific page?

I am trying to implement my own pagination, I know I can call reload which reloads the page using the current page and various search criteria, I would like to just call reload setting the page number, is this possible?

Answering my own question: You can override the search parameters using the requestHandler option/event.


Update sample ACLs to new syntax introduced by hyperledger/composer#946

Signed-off-by: James Taylor<EMAIL_ADDRESS>

 Thank you for your submission, we really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.You have signed the CLA already but the status is still pending? Let us recheck it.

Superseded by #60


service-create API failed with v1beta3 request format on Kubernetes 0.11.0 release

When trying to create service with v1beta3 request format on Kubernetes 0.11.0 release, it failed with below error.
$ kubectl create -f v1beta3_service.yaml
F0422 09:10:55.645949   32648 create.go:83] Service "frontend" is invalid: spec.port: invalid value '0': must be greater than 0 and less than 65536
$ cat v1beta3_service.yaml
{
"kind":"Service",
"apiVersion":"v1beta3",
"metadata":{
"name":"frontend",
"labels":{
"name":"frontend"
}
},
"spec":{
"ports": [
{
"port":80,
"targetPort":80,
"protocol":"TCP"
}
],
"selector":{
"name":"frontend"
}
}
}

Can you try it with the "--api-version=v1beta3" flag? Also, even though the file extension is .yaml, you meant it to be JSON, right?

This works fine on head. 0.11 does not fully support v1beta3.
Its supported after v0.15+