Skip to content

Commit 5160dfc

Browse files
author
fuscated
committed
- scripting: Add system for registring typetags from plugins, rebind LibFinder
> There is new call in ScriptingManager which makes it possible to register dynamic typetags if you have classes you have to bind and unbind to squirrel. Ideally this is done at plugin attach/release and it should be a rare thing. If the class is re-registered all old instances would be different class, but this is still really bad if it happens. > Register the lib finder class LibFinder. > Change the Wiz class to have a dynamic typetag and to be almost properly unregistered (if there are alive instances of this class and they are used after the class is unregistered there would be crashes). > Make the UI class/namespace to be private, so other binding code doesn't have access to it. git-svn-id: https://svn.code.sf.net/p/codeblocks/code/trunk@12415 2a5c6006-c6dd-42ca-98ab-0921f2732cef
1 parent 5a8b998 commit 5160dfc

File tree

9 files changed

+160
-39
lines changed

9 files changed

+160
-39
lines changed

src/include/scripting/bindings/sc_typeinfo_all.h

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ namespace ScriptBindings
3838

3939
enum class TypeTag : uint32_t
4040
{
41+
Unassigned = 0,
4142
wxString = 0x8000,
4243
wxColour,
4344
wxPoint,
@@ -66,11 +67,10 @@ enum class TypeTag : uint32_t
6667
ProjectFile,
6768
ProjectManager,
6869
ScriptingManager,
69-
UserVariableManager
70-
};
70+
UserVariableManager,
7171

72-
// Dummy type
73-
struct IONamespace{};
72+
Last
73+
};
7474

7575
template<>
7676
struct TypeInfo<wxString> {
@@ -177,13 +177,6 @@ struct TypeInfo<FileTreeData> {
177177
using baseClass = void;
178178
};
179179

180-
template<>
181-
struct TypeInfo<IONamespace> {
182-
static const uint32_t typetag = uint32_t(TypeTag::IONamespace);
183-
static constexpr const SQChar *className = _SC("IO");
184-
using baseClass = void;
185-
};
186-
187180
template<>
188181
struct TypeInfo<PluginInfo> {
189182
static const uint32_t typetag = uint32_t(TypeTag::PluginInfo);

src/include/scripting/bindings/sc_utils.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ UserDataForType<UserType>* SetupUserPointer(HSQUIRRELVM vm, SQInteger idx)
121121
{
122122
SQUserPointer ptr = nullptr;
123123
if (SQ_FAILED(sq_getinstanceup(vm, idx, &ptr,
124-
SQUserPointer(TypeInfo<UserType>::typetag))))
124+
SQUserPointer(uint64_t(TypeInfo<UserType>::typetag)))))
125125
{
126126
sq_throwerror(vm, _SC("SetupUserPointer: Invalid type tag!"));
127127
cbAssert(false);
@@ -599,7 +599,7 @@ inline SQInteger CreateClassDecl(HSQUIRRELVM v, const SQChar *className,
599599
}
600600

601601
sq_newclass(v, ((baseClassName != nullptr) ? SQTrue : SQFalse));
602-
sq_settypetag(v, -1, SQUserPointer(TypeInfo<UserType>::typetag));
602+
sq_settypetag(v, -1, SQUserPointer(uint64_t(TypeInfo<UserType>::typetag)));
603603
// Add some memory to the class. We over-allocate in cases where we store only a pointer.
604604
sq_setclassudsize(v, -1, sizeof(UserDataForType<UserType>));
605605

src/include/scriptingmanager.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,11 @@ class DLLIMPORT ScriptingManager : public Mgr<ScriptingManager>
214214
*/
215215
const TrustedScripts& GetTrustedScripts();
216216

217+
/// Return a type tag which can be used to register a class to squirrel.
218+
/// This is not infinite resource, so you have to call this rarely.
219+
/// Use TypeTag::Unassigned if you want to reset your type tag.
220+
uint32_t RequestClassTypeTag();
221+
217222
ScriptingManager(const ScriptingManager& rhs) = delete;
218223
ScriptingManager& operator=(const ScriptingManager& rhs) = delete;
219224

src/plugins/contrib/lib_finder/lib_finder.cpp

Lines changed: 93 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,9 @@
3838
#include <projectloader_hooks.h>
3939
#include <compiler.h>
4040
#include <compilerfactory.h>
41-
#include <sqplus.h>
42-
#include <sc_base_types.h>
41+
#include <sc_utils.h>
42+
#include <sc_typeinfo_all.h>
43+
#include <scriptingmanager.h>
4344
#include <logmanager.h>
4445

4546
#include "resultmap.h"
@@ -55,11 +56,6 @@ namespace
5556
// Register the plugin
5657
PluginRegistrant<lib_finder> reg(_T("lib_finder"));
5758

58-
// Some class required for scripting
59-
class LibFinder
60-
{
61-
};
62-
6359
static const bool ExtraEventPresent = true;
6460
};
6561

@@ -384,27 +380,105 @@ bool lib_finder::TryAddLibrary(CompileTargetBase* Target,LibraryResult* Result)
384380
return true;
385381
}
386382

383+
namespace ScriptBindings
384+
{
385+
386+
// Dummy type
387+
struct LibFinder{};
388+
389+
template<>
390+
struct TypeInfo<LibFinder> {
391+
static uint32_t typetag;
392+
static constexpr const SQChar *className = _SC("LibFinder");
393+
using baseClass = void;
394+
};
395+
396+
uint32_t TypeInfo<LibFinder>::typetag = uint32_t(TypeTag::Unassigned);
397+
398+
template<bool (*func)(const wxString &, cbProject *, const wxString &)>
399+
SQInteger LibFinder_LibraryToProject(HSQUIRRELVM v)
400+
{
401+
// env table, LibName, Project, TargetName
402+
ExtractParams4<SkipParam, const wxString *, cbProject *, const wxString *> extractor(v);
403+
if (!extractor.Process("LibFinder::LibraryToProject"))
404+
return extractor.ErrorMessage();
405+
const bool result = func(*extractor.p1, extractor.p2, *extractor.p3);
406+
sq_pushbool(v, result);
407+
return 1;
408+
}
409+
410+
SQInteger LibFinder_SetupTargetManually(HSQUIRRELVM v)
411+
{
412+
// env table, Target
413+
ExtractParams2<SkipParam, CompileTargetBase *> extractor(v);
414+
if (!extractor.Process("LibFinder::SetupTargetManually"))
415+
return extractor.ErrorMessage();
416+
const bool result = lib_finder::SetupTargetManually(extractor.p1);
417+
sq_pushbool(v, result);
418+
return 1;
419+
}
420+
421+
SQInteger LibFinder_EnsureIsDefined(HSQUIRRELVM v)
422+
{
423+
// env table, ShortCode
424+
ExtractParams2<SkipParam, const wxString *> extractor(v);
425+
if (!extractor.Process("LibFinder::EnsureIsDefined"))
426+
return extractor.ErrorMessage();
427+
const bool result = lib_finder::EnsureIsDefined(*extractor.p1);
428+
sq_pushbool(v, result);
429+
return 1;
430+
}
431+
432+
} // namespace ScriptBindings
433+
387434
void lib_finder::RegisterScripting()
388435
{
389-
SqPlus::SQClassDef<LibFinder>("LibFinder")
390-
.staticFunc(&lib_finder::AddLibraryToProject,"AddLibraryToProject")
391-
.staticFunc(&lib_finder::IsLibraryInProject,"IsLibraryInProject")
392-
.staticFunc(&lib_finder::RemoveLibraryFromProject,"RemoveLibraryFromProject")
393-
.staticFunc(&lib_finder::SetupTargetManually,"SetupTarget")
394-
.staticFunc(&lib_finder::EnsureIsDefined,"EnsureLibraryDefined")
395-
;
436+
ScriptingManager *scriptMgr = Manager::Get()->GetScriptingManager();
437+
HSQUIRRELVM v = scriptMgr->GetVM();
438+
if (v)
439+
{
440+
using namespace ScriptBindings;
441+
442+
TypeInfo<LibFinder>::typetag = scriptMgr->RequestClassTypeTag();
443+
444+
PreserveTop preserveTop(v);
445+
446+
sq_pushroottable(v);
447+
const SQInteger classDecl = CreateClassDecl<LibFinder>(v, _SC("LibFinder"));
448+
BindStaticMethod(v, _SC("AddLibraryToProject"),
449+
LibFinder_LibraryToProject<lib_finder::AddLibraryToProject>,
450+
_SC("LibFinder::AddLibraryToProject"));
451+
BindStaticMethod(v, _SC("IsLibraryInProject"),
452+
LibFinder_LibraryToProject<lib_finder::IsLibraryInProject>,
453+
_SC("LibFinder::IsLibraryInProject"));
454+
BindStaticMethod(v, _SC("RemoveLibraryFromProject"),
455+
LibFinder_LibraryToProject<lib_finder::RemoveLibraryFromProject>,
456+
_SC("LibFinder::RemoveLibraryFromProject"));
457+
BindStaticMethod(v, _SC("SetupTargetManually"), LibFinder_SetupTargetManually,
458+
_SC("LibFinder::SetupTargetManually"));
459+
BindStaticMethod(v, _SC("EnsureIsDefined"), LibFinder_EnsureIsDefined,
460+
_SC("LibFinder::EnsureIsDefined"));
461+
462+
// Put the class in the root table. This must be last!
463+
sq_newslot(v, classDecl, SQFalse);
464+
465+
sq_poptop(v); // Pop root table.
466+
}
396467
}
397468

398469
void lib_finder::UnregisterScripting()
399470
{
400-
Manager::Get()->GetScriptingManager();
401-
HSQUIRRELVM v = SquirrelVM::GetVMPtr();
402-
if ( v )
471+
HSQUIRRELVM v = Manager::Get()->GetScriptingManager()->GetVM();
472+
if (v)
403473
{
474+
using namespace ScriptBindings;
475+
PreserveTop preserveTop(v);
404476
sq_pushroottable(v);
405-
sq_pushstring(v,"LibFinder",-1);
406-
sq_deleteslot(v,-2,false);
477+
sq_pushstring(v, _SC("LibFinder"), -1);
478+
sq_deleteslot(v, -2, false);
407479
sq_poptop(v);
480+
481+
TypeInfo<LibFinder>::typetag = uint32_t(TypeTag::Unassigned);
408482
}
409483
}
410484

src/plugins/contrib/lib_finder/lib_finder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,15 @@ class lib_finder: public cbToolPlugin
6565
void UnregisterScripting();
6666
bool TryDownload(const wxString& ShortCode,const wxString& FileName);
6767

68+
public:
6869
// These functions are used in scripting bindings
6970
static bool AddLibraryToProject(const wxString& LibName,cbProject* Project,const wxString& TargetName);
7071
static bool RemoveLibraryFromProject(const wxString& LibName,cbProject* Project,const wxString& TargetName);
7172
static bool IsLibraryInProject(const wxString& LibName,cbProject* Project,const wxString& TargetName);
7273
static bool SetupTargetManually(CompileTargetBase* Target);
7374
static bool EnsureIsDefined(const wxString& ShortCode);
7475

76+
private:
7577
ProjectConfiguration* GetProject(cbProject* Project);
7678

7779
WX_DECLARE_HASH_MAP(cbProject*,ProjectConfiguration*,wxPointerHash,wxPointerEqual,ProjectMapT);

src/plugins/scriptedwizard/wiz.cpp

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,13 @@ namespace ScriptBindings
6262

6363
template<>
6464
struct TypeInfo<Wiz> {
65-
// FIXME (squirrel) Add a system for this
66-
static const uint32_t typetag = uint32_t(TypeTag::UserVariableManager) + 100;
65+
static uint32_t typetag;
6766
static constexpr const SQChar *className = _SC("Wiz");
6867
using baseClass = void;
6968
};
69+
70+
uint32_t TypeInfo<Wiz>::typetag = uint32_t(TypeTag::Unassigned);
71+
7072
} // namespace ScriptBindings
7173

7274
Wiz::Wiz()
@@ -98,7 +100,7 @@ void Wiz::OnAttach()
98100
}
99101

100102
// read configuration
101-
RegisterWizard(vm);
103+
RegisterWizard();
102104

103105
// run main wizard script
104106
// this registers all available wizard scripts with us
@@ -140,6 +142,28 @@ void Wiz::OnAttach()
140142
m_ReleaseObjOutputDir = _T("obj") + sep + _T("Release") + sep;
141143
}
142144

145+
void Wiz::OnRelease(bool appShutDown)
146+
{
147+
if (appShutDown)
148+
return;
149+
HSQUIRRELVM v = Manager::Get()->GetScriptingManager()->GetVM();
150+
if (v)
151+
{
152+
using namespace ScriptBindings;
153+
154+
PreserveTop preserveTop(v);
155+
sq_pushroottable(v);
156+
sq_pushstring(v, _SC("Wizard"), -1);
157+
sq_deleteslot(v, -2, false);
158+
159+
sq_pushstring(v, _SC("Wiz"), -1);
160+
sq_deleteslot(v, -2, false);
161+
sq_poptop(v);
162+
163+
TypeInfo<Wiz>::typetag = uint32_t(TypeTag::Unassigned);
164+
}
165+
}
166+
143167
int Wiz::GetCount() const
144168
{
145169
// return the number of template wizards contained in this plugin
@@ -2058,15 +2082,19 @@ SQInteger Wiz_ContainerWithChoices(HSQUIRRELVM v)
20582082

20592083
} // namespace ScriptBindings
20602084

2061-
void Wiz::RegisterWizard(HSQUIRRELVM v)
2085+
void Wiz::RegisterWizard()
20622086
{
20632087
using namespace ScriptBindings;
20642088

2089+
ScriptingManager *scriptMgr = Manager::Get()->GetScriptingManager();
2090+
HSQUIRRELVM v = scriptMgr->GetVM();
2091+
20652092
PreserveTop preserveTop(v);
20662093

20672094
sq_pushroottable(v);
20682095

20692096
{
2097+
TypeInfo<Wiz>::typetag = scriptMgr->RequestClassTypeTag();
20702098
// Register Wiz
20712099
const SQInteger classDecl = CreateClassDecl<Wiz>(v, _SC("Wiz"));
20722100

src/plugins/scriptedwizard/wiz.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include <settings.h> // needed to use the Code::Blocks SDK
1111
#include <cbexception.h>
1212
#include <wx/bitmap.h>
13-
#include <squirrel.h>
1413

1514
class wxWizard;
1615
class wxWizardPageSimple;
@@ -169,10 +168,11 @@ class Wiz : public cbWizardPlugin
169168
void AddPage(const wxString& panelName);
170169

171170
void Finalize();
172-
void RegisterWizard(HSQUIRRELVM v);
171+
void RegisterWizard();
173172
wxString FindTemplateFile(const wxString& filename);
174173
protected:
175174
void OnAttach() override;
175+
void OnRelease(bool appShutDown) override;
176176
void Clear();
177177
void CopyFiles(cbProject* theproject, const wxString& prjdir, const wxString& srcdir);
178178
wxString GenerateFile(const wxString& basePath, const wxString& filename, const wxString& contents);

src/sdk/scripting/bindings/sc_io.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,16 @@ namespace ScriptBindings
362362
namespace ScriptBindings
363363
{
364364

365+
// Dummy type
366+
struct IONamespace{};
367+
368+
template<>
369+
struct TypeInfo<IONamespace> {
370+
static const uint32_t typetag = uint32_t(TypeTag::IONamespace);
371+
static constexpr const SQChar *className = _SC("IO");
372+
using baseClass = void;
373+
};
374+
365375
void Register_IO(HSQUIRRELVM v, ScriptingManager *manager)
366376
{
367377
PreserveTop preserve(v);

src/sdk/scriptingmanager.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ struct ScriptingManager::Data : wxEvtHandler
5757
Data(ScriptingManager *scriptingManager) :
5858
m_ScriptingManager(scriptingManager),
5959
m_AttachedToMainWindow(false),
60-
m_MenuItemsManager(false) // not auto-clear
60+
m_MenuItemsManager(false), // not auto-clear
61+
m_lastTypeTag(uint32_t(ScriptBindings::TypeTag::Last))
6162
{}
6263

6364
void OnScriptMenu(wxCommandEvent& event);
@@ -117,6 +118,9 @@ struct ScriptingManager::Data : wxEvtHandler
117118
using ConstantsMap = std::unordered_map<std::string, ConstantData>;
118119
ConstantsMap m_mapConstants;
119120

121+
uint32_t m_lastTypeTag;
122+
123+
120124
friend SQInteger ConstantsGet(HSQUIRRELVM v);
121125
friend SQInteger ConstantsSet(HSQUIRRELVM v);
122126

@@ -718,3 +722,8 @@ void ScriptingManager::Data::OnScriptPluginMenu(wxCommandEvent& event)
718722
{
719723
ScriptBindings::ScriptPluginWrapper::OnScriptMenu(event.GetId());
720724
}
725+
726+
uint32_t ScriptingManager::RequestClassTypeTag()
727+
{
728+
return m_data->m_lastTypeTag++;
729+
}

0 commit comments

Comments
 (0)