-
-
Notifications
You must be signed in to change notification settings - Fork 257
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Makes topic export async (#9599) (#2592)
- Loading branch information
1 parent
508f439
commit 6890a62
Showing
10 changed files
with
118 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
|
||
/// Declars that a function is async, creates the task return type and will cause it to return the task | ||
/// upon sleeping. | ||
/// Place this as the first line in the body of the function, but after any other set X = val settings. | ||
#define DECLARE_ASYNC set waitfor = FALSE; \ | ||
RETURN_TYPE(/datum/task); \ | ||
var/datum/task/created_task = new(); \ | ||
. = created_task; | ||
|
||
/// Marks an async function as finished without returning any value. | ||
/// Async version of return; | ||
#define ASYNC_FINISH created_task.mark_completed(); \ | ||
return; | ||
|
||
/// Marks an async function as completed and returns a result. | ||
/// Async version of return value; | ||
#define ASYNC_RETURN(value) created_task.mark_completed(value);\ | ||
return; | ||
|
||
/// Waits for the provided task to be completed, or the timeout to expire. | ||
/// Returns null if the timeout expires, or the task's result otherwise. | ||
/// Note that if a task's result is null, then null will be returned. | ||
#define AWAIT(TASK, TIMEOUT) get_result(TASK, TIMEOUT) | ||
|
||
/proc/get_result(datum/task/task, timeout) | ||
if (!istype(task)) | ||
return task | ||
if (task.await(timeout)) | ||
// Return the task result | ||
return task.result | ||
return null |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/datum/task | ||
var/result = null | ||
var/completed = FALSE | ||
var/list/subtasks | ||
|
||
/// Add a subtask to this subtask. When awaiting a parent task, it will wait for all subtasks to complete | ||
/// and then will return a list containing all the results. | ||
/datum/task/proc/add_subtask(datum/task/subtask) | ||
LAZYADD(subtasks, subtask) | ||
|
||
/// Mark the task as being completed | ||
/datum/task/proc/mark_completed(result = null) | ||
if (length(subtasks)) | ||
CRASH("Attempting to mark a subtask holder as completed. This is not allowed") | ||
completed = TRUE | ||
src.result = result | ||
|
||
/// Wait for the task to be completed, or the timeout to expire | ||
/// Returns true if the task was completed | ||
/datum/task/proc/await(timeout = 30 SECONDS) | ||
var/start_time = world.time | ||
var/sleep_time = 1 | ||
while(world.time < start_time + timeout && !is_completed()) | ||
sleep(sleep_time) | ||
sleep_time = min(sleep_time * 2, 1 SECONDS) | ||
// Check for success | ||
var/success = length(subtasks) ? TRUE : completed | ||
if (length(subtasks) && !result) | ||
result = list() | ||
for (var/datum/task/subtask in subtasks) | ||
if (!subtask.completed) | ||
success = FALSE | ||
if (subtask.result) | ||
result += subtask.result | ||
return success | ||
|
||
/datum/task/proc/is_completed() | ||
if (length(subtasks)) | ||
for (var/datum/task/subtask in subtasks) | ||
if (!subtask.completed) | ||
return FALSE | ||
return TRUE | ||
return completed |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/datum/unit_test/test_async/Run() | ||
var/datum/task/task_1 = INVOKE_ASYNC(src, PROC_REF(synchronously_sleep), 1) | ||
var/datum/task/task_2 = INVOKE_ASYNC(src, PROC_REF(synchronously_sleep), 2) | ||
var/datum/task/task_3 = INVOKE_ASYNC(src, PROC_REF(synchronously_sleep), 3) | ||
var/datum/task/task_4 = INVOKE_ASYNC(src, PROC_REF(long_sleep), 4) | ||
// Long enough for the tasks to complete async, but not long enough for them to complete synchronous | ||
sleep(4) | ||
TEST_ASSERT_EQUAL(1, task_1.result, "Task 1 should have completed with a result of 1") | ||
TEST_ASSERT_EQUAL(2, task_2.result, "Task 2 should have completed with a result of 2") | ||
TEST_ASSERT_EQUAL(3, task_3.result, "Task 3 should have completed with a result of 3") | ||
TEST_ASSERT_EQUAL(FALSE, task_4.completed, "Task 4 should not have completed.") | ||
// Test this task | ||
TEST_ASSERT_EQUAL(5, AWAIT(INVOKE_ASYNC(src, PROC_REF(synchronously_sleep), 5), 3), "Awaiting a 2 ds task with a 4 ds timeout should yield the correct result.") | ||
// Test passed, behaviour is as expected | ||
|
||
/datum/unit_test/test_async/proc/synchronously_sleep(value) | ||
sleep(2) | ||
return value | ||
|
||
/datum/unit_test/test_async/proc/long_sleep(value) | ||
sleep(5) | ||
return value |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters