[Include] samp-observer.inc - Observe variables for changes
#1

samp-observer

Easily observe variables for changes. At the moment the variable is modified, the callback will be invoked.

There is no need for custom syntax, and this include does not use timers or loops to check for changes!

Example usage

Dynamic variables:
pawn Код:
new Var1, Var2;

// The value of DynVar will update every time Var1 or Var2 change
dynamic DynVar <- (Var1, Var2) {
    return Var1 * Var2;
}

main() {
    Var1 = 5;
    Var2 = 10;

    // Output: DynVar is 50
    printf("DynVar is %d", DynVar);
}
More detailed example:
pawn Код:
new g_Test = 1234;
new g_TestString[32];
new g_Array[5];
new g_ArraySum = 0;

main() {
    // Now OnTestChange will be executed
    g_Test = 789;

    print(g_TestString); // Test is 789

    // Every time this happens, OnArrayChange will be executed
    for (new i = 0; i < sizeof(g_Array); i++)
        g_Array[i] = (i + 1) * 10;

    // g_ArraySum will be automatically updated in OnArrayChange
    printf("The sum of g_Array is %d", g_ArraySum);

    for (new i = 0; i < sizeof(g_Array); i++)
        g_Array[i] *= 10;

    printf("The sum of g_Array is %d", g_ArraySum);
}

// Executed every time g_Test is changed
observer OnTestChange(previous, current) {
    printf("Test changed from %d to %d", previous, current);

    // Update a string when this value changes
    format(g_TestString, sizeof(g_TestString), "Test is %d", current);
}

// Executed every time g_Array is changed
observer OnArrayChange(prev, curr, idx) {
    printf("g_Array[%d] %d -> %d", idx, prev, curr);

    // Keep track of the array's sum without ever looping through it
    g_ArraySum += curr - prev;
}

public InstallObservers() {
    ObserveVar(g_Test, OnTestChange);
    ObserveArray(g_Array, OnArrayChange);
}
Usage and requirements

You need the amx_assembly lib. Simply place it with your include files, along with samp-observer, then include it like this:

pawn Код:
#include <samp-observer/observe>
How it's done

The include will modify the AMX code to add the function call every time an observed var/array is modified.

When you change an observed variable, the observer callback will be executed before the code continues.

Compatibility

This include is compatible with and without both crashdetect and the JIT plugin.

Limitations

You can only observe global variables and 1-dimensional arrays. I hope to bring 2-dimensional arrays to this include also!

Credits

This would not be possible without Zeex's amx_assembly lib and Y-Less's contributions to it. Most importantly, the latest codescanner addition.

GitHub
https://github.com/oscar-broman/samp-observer
Reply
#2

Nice work Slice as always, this is a game changer. This has given me an idea on how I can improve my debugging techniques!
Reply
#3

Good idea to use for debugging!

That actually got me thinking about using PrintAmxBacktrace from crashdetect within the observer. Right now it will not print the correct line number, but I think that can be fixed.

You could for example use this to keep track of TextDraws in some more complicated systems.
Reply
#4

Amazing.
Reply
#5

Great Work as always +repped
Reply
#6

Neat! Is there a way to detect automatically when a variable is created and assign a observer just after? (In the amx assembly) Perhaps a macro, like observer var; instead of new var;. Maybe not too possible right now since it doesnt support multi dimensional arrays.
Reply
#7

Quote:
Originally Posted by Marricio
Посмотреть сообщение
Neat! Is there a way to detect automatically when a variable is created and assign a observer just after? (In the amx assembly) Perhaps a macro, like observer var; instead of new var;. Maybe not too possible right now since it doesnt support multi dimensional arrays.
You can only observe global variables, but I could make a macro such as this:
pawn Код:
// Global var declared somewhere
new g_Test;

observe g_Test(prev, curr) {
    // code
}
I'll look into it.


I'm also thinking about a more advanced concept, similar to that in some react frameworks:
pawn Код:
new g_Var1, g_Var2;
new g_DynamicVar = {
    return g_Var1 * g_Var2;
};
The idea here is that g_DynamicVar will automatically update when either g_Var1 or g_Var2 is modified.

This is all possible with the current version, but you need to write a bit more code. It would be nice to have a more compact way to express these things.
Reply
#8

Good work Slice dudek
Reply
#9

This is brilliant! I will definitely be using this for debugging.
Thanks slice, perfect as always.
Reply
#10

Great release my student !
Reply
#11

This release is awesome, good work!
Reply
#12

Without your work this communitty cant be so good how it is.

Thanks for all and Nice job
Reply
#13

I added a new feature called dynamic variables.

Example:
pawn Код:
new Var1, Var2;

// The value of DynVar will update every time Var1 or Var2 change
dynamic DynVar <- (Var1, Var2) {
    return Var1 * Var2;
}

main() {
    Var1 = 5;
    Var2 = 10;

    // Output: DynVar is 50
    printf("DynVar is %d", DynVar);
}
Pure magic!
Reply
#14

this would help many
Reply
#15

AngularJS feelings. I've never thought that observer logic would be available in SA-MP. Great job!
Reply
#16

This is awesome. It'll be super useful for things like that dynamic variable feature. I've already came up with a few ideas.
Reply
#17

Great for logging, debugging and some systems like achievements...Very useful for many, many things!
Thx for such release
Reply
#18

You are a code magician Slice, good work like always, +repped.
Reply
#19

Great work slice. Another great release of you. Thank you so much, have a cookie+1.
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)