This is a small C++ implementation of the Supermemo SM2 algorithm for spaced based repetition that focuses on simplicity, portability, and testability.
It also supports the following platforms:
- iOS
- Android
- TypeScript
Every platform that LibSpacey supports includes the following scripts to help make it easier to work with multiple platforms, languages, and tools:
Name | Description |
---|---|
test.sh | Runs all tests |
lint.sh | Runs all available linters |
validate.sh | Runs tests, linters, and build (when available) |
install-dependencies.sh | Installs dependencies needed to build, lint, and run tests |
The scripts in this project assume that you are using:
- macos Catalina or greater
- homebrew
- node.js 13 or greater
- xcode 11.4 or greater
The install-dependencies.sh
scripts will take care of all basic dependencies except for xcode and node.js.
Some people prefer to use specific node.js versions, so I've left that up to you to decide what you want to use.
You can install xcode via the macos app store.
Most scripts will probably work in a different unix (e.g. Linux or FreeBSD) except for the install-dependencies.sh
scripts.
To install dependencies for all platforms run:
./scripts/install-dependencies.sh
Otherwise, feel free to go to any platform directory and run the local script there (e.g. for TypeScript):
./platforms/typescript/scripts/install-dependencies.sh
Please run the ship-it
script before pushing any new code.
It will automatically run all available tests, linters, and builds for each platform.
./scripts/ship-it.sh
LibSpacey includes a light wrapper to bridge C++ into Swift / Objective C. This allows it to be built as a framework in xcode that you can call in your projects.
You can add LibSpacey to your project with carthage.
Just add this line to your project's cartfile:
github "walterscarborough/LibSpacey" "1.1.0"
Feel free to use the LibSpaceyFlashcard
in your project, and use it with FlashcardGraderWrapper.gradeFlashcard(...)
whenever you need to grade a flashcard.
// Example:
let flashcardWrapper = FlashcardWrapper()
let gradedFlashcardWrapper = FlashcardWrapperGrader.gradeFlashcardWrapper(
flashcardWrapper,
grade: Grade.Unknown,
currentDate: Date()
)
./platforms/xcode/scripts/test.sh
Carthage can automatically build frameworks locally.
It does this by searching recursively for a .xcodeproj
file and building it.
Just run this command from the LibSpacey repo top level directory:
carthage build --archive
It will output a LibSpacey.framework.zip
file in the top level directory.
LibSpacey uses a light wrapper to bridge C++ into the JVM via JNI as an Android library. Because of this, it needs to be built separately for each architecture that you want to run it on. Android Studio should handle this automatically.
You will need to agree to the Android sdkmanager licenses to run tests from the command line:
./sdkmanager --licenses
You will also need to set the $ANDROID_SDK environment variable to the location where you have installed the Android SDK.
It's a good thing to add to your .bash_profile
if you haven't already.
You can add LibSpacey to your project by copying it into your Android Studio project folder and adding it as a gradle subproject.
// Example
val october_24_2016: Long = 1477294292
val october_25_2016: Long = 1477380692
val flashcardWrapper = FlashcardWrapper(
previousDate = october_24_2016,
nextDate = october_24_2016
)
val currentDate = Date.from(Instant.ofEpochSecond(october_24_2016))
val actualGradedFlashcardWrapper = FlashcardWrapperGrader.gradeFlashcardWrapper(
flashcardWrapper = flashcardWrapper,
grade = Grade.Unknown,
currentDate = currentDate
)
./platforms/android/scripts/test.sh
LibSpacey uses a light wrapper to bridge C++ into JavaScript by using emscripten. It also includes typings so that it can be incorporated into TypeScript projects.
For now, you can add LibSpacey to your project by building it and copying it into your project directory. It will eventually be published to NPM.
// Example
const october_24_2016 = 1477294292;
const october_25_2016 = 1477380692;
const flashcard: FlashcardWrapper = {
repetition: 0,
interval: 1,
easinessFactor: 2.5,
previousDate: october_24_2016,
nextDate: october_24_2016,
};
const flashcardModuleWrapper = new FlashcardWrapperGrader();
const actualGradedFlashcard = await flashcardModuleWrapper.gradeFlashcard(
flashcard,
Grade.Unknown,
october_24_2016
);
./platforms/typescript/scripts/test.sh
LibSpacey uses cmake to handle building and compilation, and conan for C++ package management.
1.) Build app
./common/scripts/build.sh
2.) Run tests
./common/scripts/test.sh
3.) Run linters
./common/scripts/lint.sh
3.) (optional) Run sample app
cd common
./scripts/build.sh
./cmake-build-debug/bin/libSpaceySampleApp
Contributions are welcome! Feel free to submit a pull request.
MIT -- full license file included in this repo.