Files
GacUI/.github/KnowledgeBase/manual/workflow/codegen.md
2026-02-04 14:57:24 -08:00

5.7 KiB

C++ Code Generation

Attributies can be applied to Workflow classes, functions and members to control the result of C++ code generation.

@cpp:File("YourFile")

This attribute applies toclasses. It creates a new pair of fileYourFile.handYourFile.cppto

Since internal classes in Workflow get translated to internal classes in C++, if you assign different file name to class A and B when B is defined inside A, it causes an error.

This attribute is useful when the class has methods with**@cpp:UserImpl**.

@cpp:UserImpl

This attribute applies toconstructors, destructors and functionsin classes.

Bodies of functions with**@cpp:UserImpl**are ignored, they are left blank in the generated file, allowing users to add custom code lines between:

  • / USER_CONTENT_BEGIN(CLASS-NAME) /
  • / USER_CONTENT_END() /

When a class contains methods with**@cpp:UserImpl**, custom members can also be added to the generated header file for this class between:

  • / USER_CONTENT_BEGIN(custom members of CLASS-NAME) /
  • / USER_CONTENT_END() /

When a file contains methods with**@cpp:UserImpl**, custom global declarations can also be added to the generated header file for this class between:

  • / USER_CONTENT_BEGIN(custom global declarations) /
  • / USER_CONTENT_END() /

When the Workflow script is modified and re-generated, new generated code and custom code lines in specific locations will be merged together, so your work doesn't lost.

IMPORTANT: If there are braces ({and}) in custom code lines, they must take the whole line, or the code merging will report errors.

@cpp:Protected and @cpp:Private

These attributes apply toany membersin classes, except non-auto properties.

When a class member is annotated by**@cpp:Protected**, this part of the C++ code will be generated withprotected:. So as**@cpp:Private**.

NOTE: these attributes don't affect the Workflow compiler, Workflow script treats all members as public members.

@cpp:Friend(typeof(YourType))

This attribute applies toclasses. It generatesfrienddeclaration in C++ code, allowingYourTypeto access protected or private members of the current class.

Example

Workflow Script

module SampleModule;

class DummyClass
{
    func CallPrivateMethod(my: MyClass^): void
    {
        my.Method();
    }
}

@cpp:File("MyClass")
@cpp:Friend(typeof(DummyClass))
class MyClass
{
    @cpp:UserImpl
    @cpp:Private
    func Method(): void
    {
        raise "Not Implemented!";
    }
}

Generated C++ Files

IMPORTANT:

  • The default file name is configurable, here we assume that it isSampleModule.
  • This is not the full content of generated files. By followingGenerating C++ Codeyou will see everything.

SampleModule.h

class DummyClass;
class MyClass;

class DummyClass : public ::vl::Object, public ::vl::reflection::Description<DummyClass>
{
#ifndef VCZH_DEBUG_NO_REFLECTION
    friend struct ::vl::reflection::description::CustomTypeDescriptorSelector<DummyClass>;
#endif
public:
    void CallPrivateMethod(::vl::Ptr<::MyClass> my);
    DummyClass();
};

/***********************************************************************
Global Variables and Functions
***********************************************************************/

namespace vl_workflow_global
{
    class W05Script
    {
    public:

        static W05Script& Instance();
    };
}

SampleModule.cpp

#define GLOBAL_SYMBOL ::vl_workflow_global::W05Script::
#define GLOBAL_NAME ::vl_workflow_global::W05Script::Instance().
#define GLOBAL_OBJ &::vl_workflow_global::W05Script::Instance()

/***********************************************************************
Global Variables
***********************************************************************/

BEGIN_GLOBAL_STORAGE_CLASS(vl_workflow_global_W05Script)
    vl_workflow_global::W05Script instance;
    INITIALIZE_GLOBAL_STORAGE_CLASS
    FINALIZE_GLOBAL_STORAGE_CLASS
END_GLOBAL_STORAGE_CLASS(vl_workflow_global_W05Script)

namespace vl_workflow_global
{
/***********************************************************************
Global Functions
***********************************************************************/

    W05Script& W05Script::Instance()
    {
        return Getvl_workflow_global_W05Script().instance;
    }
}

/***********************************************************************
Class (::DummyClass)
***********************************************************************/

void DummyClass::CallPrivateMethod(::vl::Ptr<::MyClass> my)
{
    ::vl::__vwsn::This(my.Obj())->Method();
}

DummyClass::DummyClass()
{
}

#undef GLOBAL_SYMBOL
#undef GLOBAL_NAME
#undef GLOBAL_OBJ

MyClass.h

class MyClass : public ::vl::Object, public ::vl::reflection::Description<MyClass>
{
    friend class ::DummyClass;
#ifndef VCZH_DEBUG_NO_REFLECTION
    friend struct ::vl::reflection::description::CustomTypeDescriptorSelector<MyClass>;
#endif
private:
    void Method();
public:
    MyClass();

/* USER_CONTENT_BEGIN(custom members of ::MyClass) */
/* USER_CONTENT_END() */
};

MyClass.cpp

#define GLOBAL_SYMBOL ::vl_workflow_global::W05Script::
#define GLOBAL_NAME ::vl_workflow_global::W05Script::Instance().
#define GLOBAL_OBJ &::vl_workflow_global::W05Script::Instance()

/* USER_CONTENT_BEGIN(custom global declarations) */
/* USER_CONTENT_END() */

/***********************************************************************
Class (::MyClass)
***********************************************************************/

void MyClass::Method()
{/* USER_CONTENT_BEGIN(::MyClass) */
    throw ::vl::Exception(L"You should implement this function.");
}/* USER_CONTENT_END() */

MyClass::MyClass()
{
}

#undef GLOBAL_SYMBOL
#undef GLOBAL_NAME
#undef GLOBAL_OBJ