项目作者: sinkingsugar

项目描述 :
Collection of pure Nim utilities
高级语言: Nim
项目地址: git://github.com/sinkingsugar/fragments.git
创建时间: 2018-07-31T07:11:21Z
项目社区:https://github.com/sinkingsugar/fragments

开源协议:MIT License

下载


Fragments

A collection of pure nim utilities.

Note: work in progress

Structure

  • ffi

    • cpp: Write C++ straight from Nim. Inspired by std/jsffi and using the magic of importcpp, macros and many other cool nim features. Wrappers are a thing of the past!
    • js: A collection of utilities for the js backend.
  • math

    • math_common: Commonly used math routines, similar to std/math.
    • vectors: Helpers for writing vectorized code, converting types into Array-Of-Structure-Of-Arrays (AOSOA) form and generalizing operations to wide types.
    • linalg: Linear algebra for 3D rendering and simulation. Designed for maximum ergonomy, performance and generalization to vectorized types and algorithms.
  • threading

    • async_primitives: Synchronization primitives for asynchronous programs, integrated with Futures and async/await.
    • atomics: Atomic types and operations closely conforming to C++11 style atomics.
    • threading_primitives: Syncrhonization primitives for multi-threaded programs, such as spin locks and events.
  • dsl: Macros to define custom Nim DSLs.

  • memory: Custom allocators and helpers for allocating objects and managing their life-time.

  • serialization: Fast binary serialization with automatically compile-time generated serializers.

Examples

ffi

cpp

  1. # Build configuration
  2. cppdefines("MYDEFINE", "MYDEFINE2=10")
  3. cppincludes(".")
  4. cppfiles("MyClass.cpp")
  5. cpplibpaths(".")
  6. # Define nim types for C++ types will be used directly
  7. defineCppType(MyClass, "MyClass", "MyClass.hpp")
  8. defineCppType(MyClass2, "MyClass2", "MyClass.hpp")
  9. # Construct an object
  10. var x = cppinit(MyClass, 1)
  11. var y = cast[ptr MyClass](alloc0(sizeof(MyClass)))
  12. # Create a C++ object tracked by the Nim GC
  13. var j: ref MyClass
  14. cppnewref(j, 1)
  15. j.number = 22
  16. echo j.number.to(cint)
  17. # Create an untracked C++ object
  18. var k: ptr MyClass
  19. cppnewptr(k, 2)
  20. k.number = 55
  21. echo k.number.to(cint)
  22. k.cppdelptr
  23. # Accessing global variables and functions
  24. echo global.globalNumber.to(cint)
  25. global.globalNumber = 102
  26. echo global.globalNumber.to(cint)
  27. global.printf("Hello World\n".cstring).to(void)
  28. # Accessing members
  29. y.test3().to(void)
  30. y.test4(7, 8).to(void)

math

vectors

  1. type
  2. MyType = object
  3. f1: int
  4. f2: float
  5. MyWideType = wide MyType
  6. var x: wide MyType
  7. x.setLane(1, x.getLane(0))

linalg

  1. var
  2. v2: Vector2
  3. v3: Vector3
  4. v4: Vector4
  5. m: Matrix4x4
  6. q: Quaternion
  7. # Construction
  8. v2 = (1.0f, 2.0f)
  9. v4 = (v2, 3.0f, 4.0f)
  10. v3 = Vector3.unitX
  11. m = Matrix4x4.identity
  12. q = Quaternion.identity
  13. # Swizzling
  14. v2.x = 3.0f
  15. q.yxz = v4.wwx
  16. v4.rgba = (v3.zxy, 1.0f)
  17. m.m00m12m34m41 = v4
  18. let v6 = v3.xyzxyz
  19. # Basic transformation
  20. let a =
  21. q = rotationAxisQuaternion(Vector3.unitX, PI/2)
  22. v3 = Vector3.unitY.transform(q)

threading

async_primitives

  1. var lock: AsyncLock
  2. lock.init()
  3. # Yield asynchronous execution until the lock is available
  4. withLock lock:
  5. await someAsynchronousOperation()

threading_primitives

Spin-locks

  1. var spinLock: SpinLock
  2. # In multiple threads
  3. withLock spinLock:
  4. someAtomicOperation()

Events

  1. var event: ManualResetEvent
  2. event.init()
  3. # Thread 1
  4. event.signal()
  5. # Thread 2
  6. event.waitOne()

atomics

  1. # Atomic flags, trivially atomic types and types that require spin-locking
  2. var
  3. guard: AtomicFlag
  4. foo: atomic int
  5. bar: atomic MyComplexType
  6. # Atomic operations
  7. var value = 5
  8. foo.store(value, moRelease)
  9. assert foo.compareExchange(value, 4, moAcquireRelease)
  10. assert foo.load(moAcquire) == 4
  11. # Possible spin-lock impelemtation
  12. while guard.testAndSet(moAcquire): discard
  13. cpuRelax()
  14. guard.clear(moRelease)

serialization

Feature:

  • Atomatic serializer generation for object and tuple types
  • Efficient handling of blittable types
  • Reuse of objects when serializing references
  1. type
  2. MyType = ref object
  3. trivial*: int
  4. skipped* {.serializable: false.}: int
  5. sequence*: seq[int]
  6. str*: string
  7. complex*: MyOtherType
  8. reference*: ref int
  9. anonymousTuple*: tuple[a: ref int]
  10. MyOtherType = object
  11. var context = newSerializationContext(stream)
  12. context.stream = newStringStream()
  13. var x = new MyType
  14. x.serialize(context)
  15. var y: MyType
  16. y.deserialize(context)

dsl

Macros to define custom nim DSLs, for example:

  1. type
  2. MyBase = object of RootObj
  3. value: string
  4. method testMethod(b: ptr MyBase; wow: ref int) {.base.} = echo "Base"
  5. archetype entity:
  6. super: MyBase
  7. mustBeVar: int
  8. mustBeVar2: float
  9. proc start()
  10. proc run(state: int) {.async.}
  11. proc stop()
  12. method testMethod(wow: ref int)
  13. entity MyEntity:
  14. param0: 10
  15. param1 {.public.}: 20
  16. var0 {.public.}: float
  17. var1: float = 2.0
  18. mustBeVar {.public.}: 10
  19. start:
  20. var ten = param0
  21. var ten2 = param1
  22. var1 = (ten + ten2).float
  23. run:
  24. echo param0
  25. echo param1
  26. echo state
  27. stop:
  28. echo param0
  29. testMethod:
  30. echo "Derived"
  31. echo param0