diff --git a/Toshi/Include/Defines.h b/Toshi/Include/Defines.h index 4515a8a..421415b 100644 --- a/Toshi/Include/Defines.h +++ b/Toshi/Include/Defines.h @@ -30,6 +30,8 @@ #define TOSHI_NAMESPACE_END } #define TOSHI_NAMESPACE_USING using namespace Toshi; +#define TSTATICCAST(type, value) static_cast(value) + #define _TS8(str) #str typedef bool TBOOL; diff --git a/Toshi/Include/TKernel/TManagedPointer.h b/Toshi/Include/TKernel/TManagedPointer.h index 3d08cac..5bc02ba 100644 --- a/Toshi/Include/TKernel/TManagedPointer.h +++ b/Toshi/Include/TKernel/TManagedPointer.h @@ -22,6 +22,12 @@ class TOSHI_EXPORT TManagedPointer delete m_pObject; } + T* operator=(T* a_pObject) + { + m_pObject = a_pObject; + return m_pObject; + } + T& operator*() { TASSERT(m_pObject != TNULL); return *m_pObject; } operator T* () { TASSERT(m_pObject!=TNULL); return m_pObject; } diff --git a/Toshi/Include/TKernel/TNTree.h b/Toshi/Include/TKernel/TNTree.h new file mode 100644 index 0000000..0c6158a --- /dev/null +++ b/Toshi/Include/TKernel/TNTree.h @@ -0,0 +1,57 @@ +#pragma once + +#include + +TOSHI_NAMESPACE_BEGIN + +class TOSHI_EXPORT TGenericNTree +{ + class TNode + { + protected: + + + TINT FindChild(TNode const* a_pNode, TINT a_iCount) + { + for (TINT i = 0; i < a_iCount; i++) { + if (a_pNode == m_pChildren[i]) { + return i; + } + } + return -1; + } + + TNode* Child(TINT a_iIndex) const { return m_pChildren[a_iIndex]; } + TNode* Parent() const { return m_pParent; } + + private: + TNode* m_pParent; // 0x0 + TNode** m_pChildren; // 0x4 + }; + +protected: + + TGenericNTree() + { + m_pRoot = TNULL; + } + + void InsertRoot(TNode *a_pNode) + { + m_pRoot = a_pNode; + a_pNode = TNULL; + } + + void RemoveRoot() + { + m_pRoot = TNULL; + } + + TNode* Root() const { return m_pRoot; } +private: + TNode* m_pRoot; // 0x0 +}; + + + +TOSHI_NAMESPACE_END \ No newline at end of file diff --git a/Toshi/Include/TKernel/TNodeTree.h b/Toshi/Include/TKernel/TNodeTree.h new file mode 100644 index 0000000..b6d14ea --- /dev/null +++ b/Toshi/Include/TKernel/TNodeTree.h @@ -0,0 +1,269 @@ +#pragma once +#include "TDebug.h" + +TOSHI_NAMESPACE_BEGIN + +// Since this won't be exported, is a template class and there is no 'TGenericNodeTree', we can't propably decompile it via ghidra +// Code from OpenToshi + +template +class TNodeTree +{ +public: + class TNode + { + public: + friend TNodeTree; + + protected: + TNode() + { + m_Tree = TNULL; + m_Next = (T*)this; + m_Prev = (T*)this; + m_Parent = TNULL; + m_Attached = TNULL; + } + + public: + TBOOL IsChildOfDefaultRoot() const + { + TASSERT(IsLinked() == TTRUE); + return m_Parent == (T*)(&Tree()->m_Root); + } + + TBOOL IsLinked() const { return m_Tree != TNULL; } + T* Parent() const { return m_Parent; } + T* Next() const { return m_Next; } + T* Prev() const { return m_Prev; } + TNodeTree* Tree() const { return m_Tree; } + T* Attached() const { return m_Attached; } + + protected: + TNodeTree* m_Tree; + T* m_Next; + T* m_Prev; + T* m_Parent; + T* m_Attached; + }; + +public: + TNodeTree() + { + m_Count = 0; + } + + ~TNodeTree() + { + DeleteAll(); + TASSERT(IsLinked() == TFALSE); + } + + /** + * Inserts node as a child of another node. + * + * @param parentNode Pointer to the parent node. + * @param sourceNode Pointer to the node you want to insert. + */ + void Insert(T* parentNode, T* sourceNode) + { + // Toshi::TNodeTree::Insert - 00691aa0 + TASSERT(sourceNode->IsLinked() == TFALSE, "The source node shouldn't be linked"); + + // Remove the source node from the tree + Remove(*sourceNode, TFALSE); + + // Get the first attached to parent node + T* firstAttached = parentNode->Attached(); + + if (firstAttached != TNULL) + { + // Attach node to other attached nodes + T* lastAttached = firstAttached->Prev(); + + lastAttached->m_Next = sourceNode; + firstAttached->m_Prev = sourceNode; + + sourceNode->m_Next = firstAttached; + sourceNode->m_Prev = lastAttached; + } + else + { + // Attach node as the first one + parentNode->m_Attached = sourceNode; + } + + sourceNode->m_Tree = this; + sourceNode->m_Parent = parentNode; + m_Count += 1; + } + + /** + * Inserts node to the default tree. + * + * @param sourceNode Pointer to the node you want to insert. + */ + void InsertAtRoot(T* sourceNode) + { + Insert(GetRoot(), sourceNode); + } + + /** + * Tries to remove sourceNode from the tree and inserts it to the parentNode or to the root + */ + void ReInsert(T* parentNode, T* sourceNode) + { + Remove(sourceNode, TFALSE); + + if (parentNode == TNULL) + { + if (this != TNULL) + { + InsertAtRoot(sourceNode); + return; + } + } + + Insert(parentNode, sourceNode); + } + + T* Remove(T& node, TBOOL flag = TFALSE) + { + // Toshi::TNodeTree::Remove - 00691e70 + TNodeTree* nodeRoot = node.Tree(); + T* nodeParent = node.Parent(); + + if (nodeRoot != TNULL) + { + // Check if the node belongs to the current tree + if (nodeRoot != this) + { + return &node; + } + + m_Count -= 1; + } + + if (flag) + { + T* attachedNode = node.Attached(); + + while (attachedNode != TNULL) + { + TNodeTree* nodeRoot = node.Tree(); + + Remove(*attachedNode, TFALSE); + Insert(node.Parent(), attachedNode); + + attachedNode = node.Attached(); + TWARNING("It seems to be unused and I hope it is. I don't know if it works and what it should do\n"); + } + } + + if (nodeParent != TNULL) + { + // If it's the first attached to the root node, set it to next or just remove + if (nodeParent->Attached() == &node) + { + nodeParent->m_Attached = (node.Next() != &node) ? node.Next() : TNULL; + } + + node.m_Parent = TNULL; + } + + node.m_Prev->m_Next = node.m_Next; + node.m_Next->m_Prev = node.m_Prev; + node.m_Next = &node; + node.m_Prev = &node; + node.m_Tree = TNULL; + return &node; + } + + T* Remove(T* node, TBOOL flag = TFALSE) + { + return Remove(*node, flag); + } + + void DeleteRecurse(T* node) + { + while (node != TNULL) + { + T* next = (node->Next() != node) ? node->Next() : TNULL; + + if (node->Attached() != TNULL) + { + DeleteRecurse(node->Attached()); + } + + if (node->Tree() == this) + { + m_Count -= 1; + } + + if (node->Tree() == TNULL || node->Tree() == this) + { + T* nodeParent = node->Parent(); + + if (nodeParent != TNULL) + { + // If it's the first attached to the root node, set it to next or just remove + if (nodeParent->Attached() == node) + { + nodeParent->m_Attached = (node->Next() != node) ? node->Next() : TNULL; + } + + node->m_Parent = TNULL; + } + + node->m_Prev->m_Parent = node->m_Next; + node->m_Next->m_Attached = node->m_Prev; + node->m_Next = node; + node->m_Prev = node; + node->m_Tree = TNULL; + } + + delete node; + node = next; + } + } + + void DeleteAll() + { + T* node = GetRoot()->Attached(); + + while (node != TNULL) + { + Remove(node, TFALSE); + DeleteRecurse(node); + node = GetRoot()->Attached(); + } + + TASSERT(Count() == 0); + } + + T* GetRoot() + { + return TSTATICCAST(T*, &m_Root); + } + + T* AttachedToRoot() + { + return m_Root.Attached(); + } + + size_t Count() const + { + return m_Count; + } + + TBOOL IsLinked() const + { + return m_Root.IsLinked(); + } + +protected: + TNode m_Root; // 0x0 + size_t m_Count; // 0x14 +}; + +TOSHI_NAMESPACE_END \ No newline at end of file diff --git a/Toshi/Include/TKernel/TScheduler.h b/Toshi/Include/TKernel/TScheduler.h index 9c8fb55..fa2b743 100644 --- a/Toshi/Include/TKernel/TScheduler.h +++ b/Toshi/Include/TKernel/TScheduler.h @@ -1,11 +1,12 @@ #pragma once -#include "TDebug.h" +#include "TObject.h" TOSHI_NAMESPACE_BEGIN -class TOSHI_EXPORT TScheduler +class TOSHI_EXPORT TScheduler : public TObject { + DECLARE_DYNAMIC(TKernelInterface); public: void Update(); }; diff --git a/Toshi/Include/TKernel/TTask.h b/Toshi/Include/TKernel/TTask.h new file mode 100644 index 0000000..a5e2b5c --- /dev/null +++ b/Toshi/Include/TKernel/TTask.h @@ -0,0 +1,38 @@ +#pragma once + +#include "TObject.h" +#include "TNodeTree.h" + +TOSHI_NAMESPACE_BEGIN + +class TOSHI_EXPORT TTask : public TObject, public TNodeTree::TNode +{ + DECLARE_DYNAMIC(TKernelInterface); + + enum State + { + State_Created = BITFIELD(0), + State_Active = BITFIELD(1), + State_Dying = BITFIELD(2), + }; + +public: + virtual TBOOL Create(); + virtual TBOOL CreateFailed(); + virtual TBOOL OnCreate(); + virtual TBOOL OnUpdate(TFLOAT a_fDeltaTime); + virtual void OnDestroy(); + virtual TBOOL OnChildDying(TTask* child); + virtual void OnChildDied(TClass* a_pClass, TTask* a_pDeletedTask); + virtual void OnActivate(); + virtual void OnDeactivate(); + + TBOOL IsCreated() const { return HASFLAG(m_iState & State_Created); } + TBOOL IsActive() const { return HASFLAG(m_iState & State_Active); } + TBOOL IsDying() const { return HASFLAG(m_iState & State_Dying); } + +private: + TINT m_iState; +}; + +TOSHI_NAMESPACE_END \ No newline at end of file diff --git a/Toshi/Source/TKernel/TKernelInterface.cpp b/Toshi/Source/TKernel/TKernelInterface.cpp index 0e2b047..0416186 100644 --- a/Toshi/Source/TKernel/TKernelInterface.cpp +++ b/Toshi/Source/TKernel/TKernelInterface.cpp @@ -23,6 +23,7 @@ TKernelInterface::TKernelInterface(TINT argc, TPCHAR* const argv, TBOOL a_bVerbo TVALIDADDRESS(pAbsSystem); pAbsSystem->SetPrefix(""); pFileManager->SetSystemPath("local"); + m_pScheduler = new TScheduler(); } TBOOL TKernelInterface::Update() diff --git a/Toshi/Source/TKernel/TScheduler.cpp b/Toshi/Source/TKernel/TScheduler.cpp index 6028a67..b9ff93f 100644 --- a/Toshi/Source/TKernel/TScheduler.cpp +++ b/Toshi/Source/TKernel/TScheduler.cpp @@ -2,6 +2,8 @@ TOSHI_NAMESPACE_USING +IMPLEMENT_DYNAMIC(TScheduler, TObject); + void TScheduler::Update() { } diff --git a/Toshi/Source/TKernel/TTask.cpp b/Toshi/Source/TKernel/TTask.cpp new file mode 100644 index 0000000..f7834d2 --- /dev/null +++ b/Toshi/Source/TKernel/TTask.cpp @@ -0,0 +1,47 @@ +#include "TTask.h" + +TOSHI_NAMESPACE_USING + +IMPLEMENT_DYNAMIC(TTask, TObject); + +TBOOL TTask::Create() +{ + TASSERT(IsCreated()==TFALSE); + return TBOOL(); +} + +TBOOL TTask::CreateFailed() +{ + return TBOOL(); +} + +TBOOL TTask::OnCreate() +{ + return TBOOL(); +} + +TBOOL TTask::OnUpdate(TFLOAT a_fDeltaTime) +{ + return TBOOL(); +} + +void TTask::OnDestroy() +{ +} + +TBOOL TTask::OnChildDying(TTask* child) +{ + return TBOOL(); +} + +void TTask::OnChildDied(TClass* a_pClass, TTask* a_pDeletedTask) +{ +} + +void TTask::OnActivate() +{ +} + +void TTask::OnDeactivate() +{ +}