Add Home
170
Home.md
Normal file
170
Home.md
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
|
||||||
|
# Conflux Programming Guide
|
||||||
|
|
||||||
|
The `Ctx` class in the `conflux` package is a lightweight, type-safe, generic, application-wide context. It provides key-based, strongly typed storage with thread-safe put/get, type consistency for each key, and listener support to observe changes. Listeners are weakly referenced to avoid memory leaks. `Ctx` is ideal for coordinating shared data among otherwise decoupled classes.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
First, import the required classes:
|
||||||
|
|
||||||
|
```java
|
||||||
|
import conflux.Ctx;
|
||||||
|
import conflux.Key;
|
||||||
|
import conflux.Listener;
|
||||||
|
````
|
||||||
|
|
||||||
|
## Creating Keys
|
||||||
|
|
||||||
|
Define typed keys for the data you want to store:
|
||||||
|
|
||||||
|
```java
|
||||||
|
Key<Integer> counterKey = new Key<>("counter", Integer.class);
|
||||||
|
Key<String> nameKey = new Key<>("name", String.class);
|
||||||
|
Key<int[]> arrayKey = new Key<>("numbers", int[].class);
|
||||||
|
Key<MyPojo> pojoKey = new Key<>("myPojo", MyPojo.class);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Storing and Retrieving Values
|
||||||
|
|
||||||
|
### Storing
|
||||||
|
|
||||||
|
```java
|
||||||
|
Ctx.INSTANCE.put(counterKey, 42);
|
||||||
|
Ctx.INSTANCE.put(nameKey, "Alice");
|
||||||
|
Ctx.INSTANCE.put(arrayKey, new int[]{1, 2, 3});
|
||||||
|
Ctx.INSTANCE.put(pojoKey, new MyPojo("Widget", 99));
|
||||||
|
```
|
||||||
|
|
||||||
|
### Retrieving
|
||||||
|
|
||||||
|
```java
|
||||||
|
Integer counter = Ctx.INSTANCE.get(counterKey);
|
||||||
|
System.out.println("Counter: " + counter);
|
||||||
|
|
||||||
|
String name = Ctx.INSTANCE.get(nameKey);
|
||||||
|
System.out.println("Name: " + name);
|
||||||
|
|
||||||
|
int[] numbers = Ctx.INSTANCE.get(arrayKey);
|
||||||
|
System.out.println("Numbers: " + Arrays.toString(numbers));
|
||||||
|
|
||||||
|
MyPojo pojo = Ctx.INSTANCE.get(pojoKey);
|
||||||
|
System.out.println("POJO: " + pojo);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Listening for Changes
|
||||||
|
|
||||||
|
You can attach listeners to keys so other classes can react when a value changes. Listeners are weakly referenced to avoid memory leaks.
|
||||||
|
|
||||||
|
```java
|
||||||
|
Listener<Integer> counterListener = newValue ->
|
||||||
|
System.out.println("Counter changed to " + newValue);
|
||||||
|
|
||||||
|
Ctx.INSTANCE.addListener(counterKey, counterListener);
|
||||||
|
|
||||||
|
Ctx.INSTANCE.put(counterKey, 100); // triggers listener
|
||||||
|
Ctx.INSTANCE.put(counterKey, 200); // triggers listener again
|
||||||
|
|
||||||
|
Ctx.INSTANCE.removeListener(counterKey, counterListener);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Working with Arrays
|
||||||
|
|
||||||
|
```java
|
||||||
|
int[] oldArray = new int[]{1, 2, 3};
|
||||||
|
int[] newArray = new int[]{4, 5, 6};
|
||||||
|
|
||||||
|
Ctx.INSTANCE.put(arrayKey, oldArray);
|
||||||
|
|
||||||
|
Ctx.INSTANCE.addListener(arrayKey, newValue ->
|
||||||
|
System.out.println("Array changed to " + Arrays.toString(newValue))
|
||||||
|
);
|
||||||
|
|
||||||
|
Ctx.INSTANCE.put(arrayKey, newArray); // triggers listener
|
||||||
|
```
|
||||||
|
|
||||||
|
## Using with Objects
|
||||||
|
|
||||||
|
Define a simple POJO:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class MyPojo {
|
||||||
|
private final String name;
|
||||||
|
private final int price;
|
||||||
|
|
||||||
|
public MyPojo(String name, int price) {
|
||||||
|
this.name = name;
|
||||||
|
this.price = price;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name + " ($" + price + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
And store it:
|
||||||
|
|
||||||
|
```java
|
||||||
|
MyPojo initialPojo = new MyPojo("Widget", 50);
|
||||||
|
|
||||||
|
Ctx.INSTANCE.put(pojoKey, initialPojo);
|
||||||
|
|
||||||
|
Ctx.INSTANCE.addListener(pojoKey, newValue ->
|
||||||
|
System.out.println("POJO changed to " + newValue)
|
||||||
|
);
|
||||||
|
|
||||||
|
Ctx.INSTANCE.put(pojoKey, new MyPojo("Widget Pro", 99)); // triggers listener
|
||||||
|
```
|
||||||
|
|
||||||
|
## Type Safety
|
||||||
|
|
||||||
|
Once a key is registered with a type, you cannot use the same name with a different type:
|
||||||
|
|
||||||
|
```java
|
||||||
|
Key<Integer> myKey = new Key<>("sharedKey", Integer.class);
|
||||||
|
Ctx.INSTANCE.put(myKey, 5);
|
||||||
|
|
||||||
|
// later:
|
||||||
|
Key<String> badKey = new Key<>("sharedKey", String.class);
|
||||||
|
Ctx.INSTANCE.put(badKey, "wrong type"); // throws IllegalStateException
|
||||||
|
```
|
||||||
|
|
||||||
|
## Removing and Clearing
|
||||||
|
|
||||||
|
Remove a single key and its listeners:
|
||||||
|
|
||||||
|
```java
|
||||||
|
Ctx.INSTANCE.remove(nameKey);
|
||||||
|
```
|
||||||
|
|
||||||
|
Or clear everything:
|
||||||
|
|
||||||
|
```java
|
||||||
|
Ctx.INSTANCE.clear();
|
||||||
|
```
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
* Define your keys as constants to keep them consistent
|
||||||
|
* Register listeners in classes that depend on context changes
|
||||||
|
* Remove listeners when no longer needed (though weak references help)
|
||||||
|
* Use unique key names to avoid collisions
|
||||||
|
|
||||||
|
## Complete Example
|
||||||
|
|
||||||
|
```java
|
||||||
|
Key<Integer> temperatureKey = new Key<>("temperature", Integer.class);
|
||||||
|
|
||||||
|
Listener<Integer> display = t ->
|
||||||
|
System.out.println("Temperature changed to " + t + "°C");
|
||||||
|
|
||||||
|
Ctx.INSTANCE.addListener(temperatureKey, display);
|
||||||
|
|
||||||
|
Ctx.INSTANCE.put(temperatureKey, 20);
|
||||||
|
Ctx.INSTANCE.put(temperatureKey, 25);
|
||||||
|
|
||||||
|
Ctx.INSTANCE.removeListener(temperatureKey, display);
|
||||||
|
|
||||||
|
Ctx.INSTANCE.put(temperatureKey, 30); // no notification after listener removed
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user